React Native 防止上下文依赖重新渲染所有组件 [英] React Native Prevent Context Dependency Rerender All Components
问题描述
我有三个按钮.当我单击一个按钮时,它会触发 Context 的备忘录功能以将一个项目添加到 Context 的项目中.我看到单击一个按钮会重新呈现所有三个按钮,这是意料之中的.我只需要重新渲染点击的按钮.请指教.
CounterContext.js
import { createContext } from react";export const CounterContext = createContext(null);
App.js
从反应"导入反应;import { Text, StyleSheet } from react-native";从./MyButton"导入 MyButton;import { CounterContext } from "./CounterContext";函数 counterReducer(prevState, action) {开关(动作.类型){案例ADD_ITEM":让 items = [...prevState.items, action.item];返回 {物品:物品,计数:items.length};默认:console.log(无操作类型");休息;}}const 按钮 = [1"、2"、3"];导出默认函数 App() {const [counterState, counterDispatch] = React.useReducer(counterReducer, {项目: [],计数:0});const counterContext = React.useMemo(() =>({添加项目:项目 =>{counterDispatch({类型:ADD_ITEM",项目:项目});},项目:counterState.items,itemsCount: counterState.items.length}),[counterState.items]);返回 (<CounterContext.Provider value={counterContext}>{buttons.map((button, index) => {返回 <MyButton key={index} id={button}/>;})}<Text style={styles.counter}>{counterContext.itemsCount}</Text><Text style={styles.items}>{JSON.stringify(counterContext.items)}</Text></CounterContext.Provider>);}const 样式 = StyleSheet.create({柜台: {保证金:10,字体大小:30},项目: {保证金:10,字体大小:18}});
MyButton.js
从反应"导入反应;import { TouchableOpacity, Text, StyleSheet } from react-native";import { CounterContext } from "./CounterContext";导出默认函数 MyButton(props) {const { addItem } = React.useContext(CounterContext);让时间 = new Date().toLocaleTimeString();console.log(time + "-Rendering MyButton #" + props.id + "...");返回 (<TouchableOpacitystyle={styles.myButton}onPress={() =>{新增项目({名称:项目#"+ props.id});}}><文本>添加</文本></TouchableOpacity>);}const 样式 = StyleSheet.create({我的按钮:{宽度:100,保证金:10,填充:10,文本对齐:居中",边框宽度:1,边框颜色:#ccc",背景颜色:#e0e0e0",边界半径:5}});
这是 Codesandbox 代码:
原来我必须将 Context 拆分为两个,一个没有依赖关系,只运行函数,另一个显示任何值) 实时通过添加依赖项.与消费者组件相同,将其作为新组件取出并放入useContext
,这样父组件就不会被重新渲染.
I have three buttons. When I click one button, it fires Context's memo function to add an item into Context's items. I see that clicking one button re-renders all the three buttons, which is not expected. I need to re-render only the clicked button. Please advice.
CounterContext.js
import { createContext } from "react";
export const CounterContext = createContext(null);
App.js
import React from "react";
import { Text, StyleSheet } from "react-native";
import MyButton from "./MyButton";
import { CounterContext } from "./CounterContext";
function counterReducer(prevState, action) {
switch (action.type) {
case "ADD_ITEM":
let items = [...prevState.items, action.item];
return {
items: items,
count: items.length
};
default:
console.log("No action type");
break;
}
}
const buttons = ["1", "2", "3"];
export default function App() {
const [counterState, counterDispatch] = React.useReducer(counterReducer, {
items: [],
count: 0
});
const counterContext = React.useMemo(
() => ({
addItem: item => {
counterDispatch({
type: "ADD_ITEM",
item: item
});
},
items: counterState.items,
itemsCount: counterState.items.length
}),
[counterState.items]
);
return (
<CounterContext.Provider value={counterContext}>
{buttons.map((button, index) => {
return <MyButton key={index} id={button} />;
})}
<Text style={styles.counter}>{counterContext.itemsCount}</Text>
<Text style={styles.items}>{JSON.stringify(counterContext.items)}</Text>
</CounterContext.Provider>
);
}
const styles = StyleSheet.create({
counter: {
margin: 10,
fontSize: 30
},
items: {
margin: 10,
fontSize: 18
}
});
MyButton.js
import React from "react";
import { TouchableOpacity, Text, StyleSheet } from "react-native";
import { CounterContext } from "./CounterContext";
export default function MyButton(props) {
const { addItem } = React.useContext(CounterContext);
let time = new Date().toLocaleTimeString();
console.log(time + " - Rendering MyButton #" + props.id + " ...");
return (
<TouchableOpacity
style={styles.myButton}
onPress={() => {
addItem({
name: "Item #" + props.id
});
}}
>
<Text>Add</Text>
</TouchableOpacity>
);
}
const styles = StyleSheet.create({
myButton: {
width: 100,
margin: 10,
padding: 10,
textAlign: "center",
borderWidth: 1,
borderColor: "#ccc",
backgroundColor: "#e0e0e0",
borderRadius: 5
}
});
Here is the Codesandbox codes: https://codesandbox.io/s/usecontext-dependency-fpcep?file=/src/App.js
Turns out that I have to split Context into two, one that doesn’t have dependency, only to run the functions, and one that shows any value(s) real-time by adding the dependency. The same with the consumer component(s), take it out as new component and put the useContext
in there, so parent component won’t be re-rendered.
这篇关于React Native 防止上下文依赖重新渲染所有组件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!