Reactjs 如何根据道具更改更好地更新多个状态

Reactjs 如何根据道具更改更好地更新多个状态,reactjs,react-hooks,Reactjs,React Hooks,假设我有一个带有排序数据的表,我想将它存储在一个(甚至是3个分离的状态)上。假设此状态可以由子级更改。 如果没有3个不同的,我想看看是否有可能在只使用1个效果的情况下达到与下面相同的效果 import React, { useState, useEffect } from "react"; function Table({ initialSortDirection, initialSortParam, initialSortEnabled }) { const [currentSort

假设我有一个带有排序数据的表,我想将它存储在一个(甚至是3个分离的状态)上。假设此状态可以由子级更改。 如果没有3个不同的,我想看看是否有可能在只使用1个效果的情况下达到与下面相同的效果

import React, { useState, useEffect } from "react";

function Table({ initialSortDirection, initialSortParam, initialSortEnabled }) {
    const [currentSortData, setSortData] = useState({
        sortDirection: initialSortDirection,
        sortParam: initialSortParam,
        hasSort: initialSortEnabled
    });
    useEffect(() => {
        setSortData({ ...currentSortData, sortDirection: initialSortDirection });
    }, [initialSortDirection]);
    useEffect(() => {
        setSortData({ ...currentSortData, sortParam: initialSortParam });
    }, [initialSortParam]);
    useEffect(() => {
        setSortData({ ...currentSortData, hasSort: initialSortEnabled });
    }, [initialSortEnabled]);
   return (<SomeComponent onChangeSort={setSortData} />)
}
import React,{useState,useffect}来自“React”;
函数表({initialSortDirection,initialSortParam,initialSortEnabled}){
常量[currentSortData,setSortData]=useState({
sortDirection:初始化sortDirection,
排序图:初始排序图,
hasSort:已初始化
});
useffect(()=>{
setSortData({…currentSortData,sortDirection:initialSortDirection});
},[initialSortDirection]);
useffect(()=>{
setSortData({…currentSortData,sortParam:initialSortParam});
},[initialSortParam]);
useffect(()=>{
setSortData({…currentSortData,hasSort:initialSortEnabled});
},[初始化];
返回()
}
按照老派的方式,我可能会使用并只是比较nextProps,看看它们是否发生了变化,但现在我很难找到一种简洁的方式“立即”并且只在变化的情况下完成

作为一个可视化的例子,考虑下面的图像,你可以通过点击单元格或者改变“旋钮”来改变排序。 编辑1

假设其他事情可能会影响状态,我不想用未更改的初始属性覆盖更新的状态。我相应地更新了代码

编辑2
添加了故事书图片

您可以拥有一个useffect(),它可以监听很少的状态变化:

useEffect(() => {
  setSortData({
    ...currentSortData,
    sortDirection: initialSortDirection,
    sortParam: initialSortParam,
    hasSort: initialSortEnabled
  });
}, [initialSortDirection, initialSortParam, initialSortEnabled]);

这就是你想要的行为吗

下面是我将如何使用一个
useffect()
来实现它

我会将
道具
最后的值(来自上一次渲染)保存在
useRef
中,并检查每个属性的差异,决定是否更新
状态
。之后,我将
ref
值更新为当前的
props
,以便在下一次渲染期间对照未来的
props
进行检查,依此类推

函数应用程序(){
常量[initialState,setInitialState]=React.useState({
首字母PROP1:'A',
首字母PROP2:“A”
});
返回(
);
}
函数表({initialProp1,initialProp2,setInitialState}){
const[myState,setMyState]=React.useState({
prop1:缩写prop1,
prop2:初始值prop2
});
const lastProps=React.useRef({
首字母PROP1,
首字母PROP2
});
React.useffect(()=>{
如果(lastProps.current.initialProp1!==initialProp1){
console.log('1已更改');
setMyState((prevState)=>{
返回({
…国家,
prop1:初始值prop1
});
});
}
如果(lastProps.current.initialProp2!==initialProp2){
console.log('2已更改');
setMyState((prevState)=>{
返回({
…国家,
prop2:初始值prop2
});
});
}
lastProps.current={
首字母PROP1,
首字母PROP2
}
});
函数changeState(){
setMyState((prevState)=>{
返回({
…国家,
建议二:"B"
});
});
}
函数changeProps(){
设置初始状态({
首字母PROP1:'A',
首字母PROP2:'C'
});
}
返回(
这是表props initialProp1:{initialProp1}
这是表props initialProp2:{initialProp2}
这是表状态prop1:{myState.prop1}
这是表状态prop2:{myState.prop2}
更改表状态
更改来自家长的道具
);
}
ReactDOM.render(,document.getElementById('root'))

我在面对类似问题时遇到了这个问题,但对CBD开发人员对他使用
useRef
的回答不满意,因为我觉得你不需要这个。reactflux的一位友好人士指出了一个更优雅的解决方案:

const表=(道具)=>{
const{initialSortDirection,initialSortParam,initialSortEnabled}=props;
常量[currentSortData,setSortData]=useState({
sortDirection:初始化sortDirection,
排序图:初始排序图,
hasSort:已初始化
});
useffect(()=>{
setSortData((prevSortData)=>({
…前SortData,
sortDirection:初始化sortDirection
}));
},[initialSortDirection]);
useEffect((prevSortData)=>{
setSortData(()=>({
…前SortData,
排序图:初始排序图
});
},[initialSortParam]);
useffect(()=>{
setSortData((prevSortData)=>({
…前SortData,
hasSort:已初始化
}));
},[初始化];
返回()
}
我知道您希望将所有内容合并为一个,但我不建议您这样做。您希望将关注点分开,在道具更新时始终激发正确的效果

请注意,OP解决方案是假的,就像两个道具同时更新一样,在使用多个效果时,只有最后一个状态更改将持续


希望这对某人有所帮助。

我假设你的道具(
initialSortDirection
initialsortpram
initialsorted
)总是有值吗?是的,假设它们将被正确初始化或有一个DefaultProps。您是否担心,如果单击标题单元格进行排序,该排序将覆盖通过props得到的初始状态?@cbdev420否,这是所需的行为。问题是,某些更改的状态将被旧的initialState覆盖如果只有一个initialState更改,一个很好的例子是,如果我通过更改initialSortEnabled来禁用排序,我可能会丢失