我在子组件AddMore.js
中有一个按钮,该按钮可在列表中添加更多项,但它不会重新渲染呈现该列表Pig.js
的其他子组件。我认为我的设置会起作用,因为我使用NextJS框架以类似的方式设置了上下文和提供程序。 Here's the source code, using codesandbox,或者您可以查看下面的代码。
App.js
import React, { useState } from "react";
import "./App.css";
import PigContext from "./store/PigContext";
import Pig from "./Pig";
import AddMore from "./AddMore";
function App() {
const [data, setData] = useState([
{ pig: "oink" },
{ pig: "bork" },
{ pig: "oinkoink" }
]);
return (
<div className="App">
<header className="App-header">
<PigContext.Provider value={{ data, setData }}>
<Pig />
<AddMore />
</PigContext.Provider>
</header>
</div>
);
}
export default App;
PigContext.js
import { createContext } from "react";
const PigContext = createContext(undefined);
export default PigContext;
Pig.js
import React, { useContext } from "react";
import PigContext from "./store/PigContext";
const Pig = () => {
const { data } = useContext(PigContext);
return (
<div>
{data.map(({ pig }, idx) => (
<div key={idx}>{pig}</div>
))}
</div>
);
};
export default Pig;
AddMore.js
import React, { useContext } from "react";
import PigContext from "./store/PigContext";
export default function AddMore() {
const { setData } = useContext(PigContext);
return (
<div>
<button
onClick={() =>
setData(prev => {
prev.push({ pig: "zoink" });
console.log(prev);
return prev;
})
}
>
add pig question
</button>
</div>
);
}
答案 0 :(得分:2)
您要通过调用push
来更改状态对象,而应该返回一个新数组来更新组件。
AddMore.js:
...
<button
onClick={() =>
setData(prev => (
[...prev, ({ pig: "zoink" })]
))
}
>
...
答案 1 :(得分:0)
这是因为您在setData中使用push处于突变状态。使用不会改变状态的方法(例如concat)可以解决此问题。您的AddMore函数看起来像
function AddMore() {
const { setData } = useContext(PigContext);
return (
<div>
<button onClick={() => setData(prev => prev.concat({ pig: "zoink" }))}>
add pig question
</button>
</div>
);
}