我在尝试使用React Context API时发现,每次值改变时提供程序都会渲染两次。
以下是我的操作步骤:
1. 创建了一个上下文,然后创建了一个组件来渲染其提供程序。 2. 提供程序提供了一个状态值及其setter。 3. 创建了一个直接子级,直接渲染其子级。 4. 创建了一个消费者,该消费者读取上下文值并添加一个按钮来更改它。 5. 每个组件在渲染时都会执行console.log。 6. 在提供程序中添加了一个effect而没有deps,以记录每次渲染。 7. 在提供程序中添加了一个ref,在每次渲染时递增,并在渲染和效果中进行记录。
问题是,每次我点击按钮更改上下文值时,提供程序都会渲染两次,但效果仅执行一次。
因此,ref始终递增两次,但效果每次仅获取最后一个值(跳过一个值!)。
此外,在提供程序的第一次呈现中,它记录了两次相同的ref值,这对我来说非常奇怪。
有人能告诉我为什么会出现这种行为吗?
以下是代码:
两个孩子
以下是我的操作步骤:
1. 创建了一个上下文,然后创建了一个组件来渲染其提供程序。 2. 提供程序提供了一个状态值及其setter。 3. 创建了一个直接子级,直接渲染其子级。 4. 创建了一个消费者,该消费者读取上下文值并添加一个按钮来更改它。 5. 每个组件在渲染时都会执行console.log。 6. 在提供程序中添加了一个effect而没有deps,以记录每次渲染。 7. 在提供程序中添加了一个ref,在每次渲染时递增,并在渲染和效果中进行记录。
问题是,每次我点击按钮更改上下文值时,提供程序都会渲染两次,但效果仅执行一次。
因此,ref始终递增两次,但效果每次仅获取最后一个值(跳过一个值!)。
此外,在提供程序的第一次呈现中,它记录了两次相同的ref值,这对我来说非常奇怪。
有人能告诉我为什么会出现这种行为吗?
以下是代码:
const MyContext = React.createContext(0);
function Provider({ children }) {
const state = React.useState("Yes");
const ref = React.useRef(0);
ref.current += 1;
console.log("Context provider ", ref.current);
React.useEffect(() => {
console.log("effect on provider, ref value = ", ref.current);
});
return <MyContext.Provider value={state}>{children}</MyContext.Provider>;
}
两个孩子
function DirectChild({ children }) {
console.log("provider direct child");
return children;
}
function Consumer() {
console.log("consumer");
const [state, setState] = React.useContext(MyContext);
return (
<div>
<span>State value: {state}</span>
<br />
<button onClick={() => setState(old => old + "Yes")}>Change</button>
</div>
);
}
这个应用程序
export default function App() {
console.log("APP");
return (
<Provider>
<DirectChild>
<Consumer />
</DirectChild>
</Provider>
);
}
这里有一个codesandbox演示
App
中,导致渲染两次,记录两次,并且只有一个效果。这里是演示。 - undefineduseState
)。虽然我猜你可以用它们来引用任何东西,但不确定这是否符合其意图:"避免使用refs来处理可以以声明方式完成的事情"。 - undefined