Smi*_*yne 50 javascript reactjs redux
我在 React 中将 Redux 与类组件一起使用。在 Redux 商店中具有以下两种状态。
{ spinner: false, refresh: false }
Run Code Online (Sandbox Code Playgroud)
在父组件中,我有一个调度函数来改变这个状态。
class App extends React.Component {
reloadHandler = () => {
console.log("[App] reloadComponent");
this.props.onShowSpinner();
this.props.onRefresh();
};
render() {
return <Child reloadApp={this.reloadHandler} />;
}
}
Run Code Online (Sandbox Code Playgroud)
在子组件中,我试图重新加载父组件,如下所示。
class Child extends React.Component {
static getDerivedStateFromProps(props, state) {
if (somecondition) {
// doing some redux store update
props.reloadApp();
}
}
render() {
return <button />;
}
}
Run Code Online (Sandbox Code Playgroud)
我收到如下错误。
警告:无法从不同组件的函数体内部更新组件。
如何消除此警告?我在这里做错了什么?
Dom*_*nic 46
对我来说,我是在 React Hook 中分派到我的 redux 商店。我必须在 a 中调度以useEffect与 React 渲染周期正确同步:
export const useOrderbookSubscription = marketId => {
const { data, error, loading } = useSubscription(ORDERBOOK_SUBSCRIPTION, {
variables: {
marketId,
},
})
const formattedData = useMemo(() => {
// DISPATCHING HERE CAUSED THE WARNING
}, [data])
// DISPATCHING HERE CAUSED THE WARNING TOO
// Note: Dispatching to the store has to be done in a useEffect so that React
// can sync the update with the render cycle otherwise it causes the message:
// `Warning: Cannot update a component from inside the function body of a different component.`
useEffect(() => {
orderbookStore.dispatch(setOrderbookData(formattedData))
}, [formattedData])
return { data: formattedData, error, loading }
}
Run Code Online (Sandbox Code Playgroud)
Jai*_*Jai 21
您似乎拥有最新版本的React@16.13.x. 您可以在此处找到有关它的更多详细信息。指定您不应setState从其他组件中分离出另一个组件。
从文档:
支持在渲染过程中调用 setState,但仅限于同一组件。如果您在不同组件上的渲染期间调用 setState,您现在将看到一条警告:
Warning: Cannot update a component from inside the function body of a different component.
此警告将帮助您查找由无意状态更改引起的应用程序错误。在极少数情况下,您故意希望更改另一个组件的状态作为渲染的结果,您可以将 setState 调用包装到 useEffect 中。
来到实际问题。
我认为getDerivedStateFromProps在子组件主体中不需要。如果要触发绑定事件。然后你可以通过onClick子组件的调用它,因为我可以看到它是一个<button/>.
class Child extends React.Component {
constructor(props){
super(props);
this.updateState = this.updateState.bind(this);
}
updateState() { // call this onClick to trigger the update
if (somecondition) {
// doing some redux store update
this.props.reloadApp();
}
}
render() {
return <button onClick={this.updateState} />;
}
}
Run Code Online (Sandbox Code Playgroud)
rad*_*huq 21
如果您的代码在满足如下条件时调用父组件中的函数:
const ListOfUsersComponent = ({ handleNoUsersLoaded }) => {
const { data, loading, error } = useQuery(QUERY);
if (data && data.users.length === 0) {
return handleNoUsersLoaded();
}
return (
<div>
<p>Users are loaded.</p>
</div>
);
};
Run Code Online (Sandbox Code Playgroud)
尝试将条件包装在 a 中useEffect:
const ListOfUsersComponent = ({ handleNoUsersLoaded }) => {
const { data, loading, error } = useQuery(QUERY);
useEffect(() => {
if (data && data.users.length === 0) {
return handleNoUsersLoaded();
}
}, [data, handleNoUsersLoaded]);
return (
<div>
<p>Users are loaded.</p>
</div>
);
};
Run Code Online (Sandbox Code Playgroud)
Jas*_*ing 13
tl;博士包装状态更新setTimeout修复它。
这种情况导致了 IMO 是有效用例的问题。
const [someState, setSomeState] = useState(someValue);
const doUpdate = useRef((someNewValue) => {
setSomeState(someNewValue);
}).current;
return (
<SomeComponent onSomeUpdate={doUpdate} />
);
Run Code Online (Sandbox Code Playgroud)
使固定
const [someState, setSomeState] = useState(someValue);
const doUpdate = useRef((someNewValue) => {
setTimeout(() => {
setSomeState(someNewValue);
}, 0);
}).current;
return (
<SomeComponent onSomeUpdate={doUpdate} />
);
Run Code Online (Sandbox Code Playgroud)
就我而言,我错过了箭头功能 ()=>{}
代替 onDismiss={()=>{/*do something*/}}
我有它 onDismiss={/*do something*/}
升级 react 和 react native 后我遇到了同样的问题,我只是通过将 props.navigation.setOptions 放在 useEffect 中解决了这个问题。如果有人面临与我相同的问题,我只想建议他改变您的状态或在 useEffect 中进行任何操作
| 归档时间: |
|
| 查看次数: |
87390 次 |
| 最近记录: |