Reactjs 反应挂钩,在选择上设置状态
我试图给我的数据添加排序功能,但我有一些问题,我决定尝试使用React钩子,但不确定我是否做错了什么,问题是当我通过选择选择某个值时,即使状态已更改,页面上也没有差异,在我第二次单击另一个值后,如果我单击同一个元素,则没有任何更改,然后一切开始正常工作,每次单击某个值,都会应用不同的排序方式。为什么从一开始它就不想正常工作 编辑: 首先在父组件中获取数据,然后通过道具传递数据: 家长:Reactjs 反应挂钩,在选择上设置状态,reactjs,select,react-hooks,Reactjs,Select,React Hooks,我试图给我的数据添加排序功能,但我有一些问题,我决定尝试使用React钩子,但不确定我是否做错了什么,问题是当我通过选择选择某个值时,即使状态已更改,页面上也没有差异,在我第二次单击另一个值后,如果我单击同一个元素,则没有任何更改,然后一切开始正常工作,每次单击某个值,都会应用不同的排序方式。为什么从一开始它就不想正常工作 编辑: 首先在父组件中获取数据,然后通过道具传递数据: 家长: const [data, setData] = useState("") useEffect(() =&
const [data, setData] = useState("")
useEffect(() => getDeviceDataTotal(), [])
const getDeviceDataTotal = () => {
console.log('refresh clicked')
fetch("http://localhost:4000/device")
.then(res => res.json())
.then((res) => setData(res))
.catch(err => {
throw err;
});
};
<Route
exact
path="/"
render={() => <Dashboard classes={classes} data={data} refresh={getDeviceDataTotal}/> }
/>
子组件:
function Dashboard(props) {
const [selectedSort, setSelectedSort] = useState("1")
const [devices, setDevices] = useState(props.data)
useEffect(() => {
props.refresh();
setDevices(props.data)
},[devices])
useEffect(() => sortDeviceData(), [selectedSort])
const sortDeviceData = () => {
console.log(devices)
switch(selectedSort) {
case "device":
console.log(devices)
props.data.sort(function(a,b) {
return (a.device_id.toUpperCase() < b.device_id.toUpperCase()) ? -1 : (a.device_id.toUpperCase() > b.device_id.toUpperCase()) ? 1 : 0
})
setDevices(props.data)
break;
case "customer":
props.data.sort(function(a,b) {
return (a.customer.toUpperCase() < b.customer.toUpperCase()) ? -1 : (a.customer.toUpperCase() > b.customer.toUpperCase()) ? 1 : 0
})
setDevices(props.data)
break;
case "server":
props.data.sort(function(a,b) {
return (a.server.toUpperCase() < b.server.toUpperCase()) ? -1 : (a.server.toUpperCase() > b.server.toUpperCase()) ? 1 : 0
})
setDevices(props.data)
break;
case "creation":
props.data.sort(function(a,b) {
return (a.createdAt.toUpperCase() < b.createdAt.toUpperCase()) ? -1 : (a.createdAt.toUpperCase() > b.createdAt.toUpperCase()) ? 1 : 0
})
setDevices(props.data)
break;
case "update":
props.data.sort(function(a,b) {
return (a.updatedAt.toUpperCase() < b.updatedAt.toUpperCase()) ? -1 : (a.updatedAt.toUpperCase() > b.updatedAt.toUpperCase()) ? 1 : 0
})
setDevices(props.data)
break;
default:
return setDevices(props.data)
}
}
<div>
<FormControl className={classes.selectContainer}>
<Select
value={selectedSort}
style={{position: 'absolute', right: 0, bottom: 10, width: 150}}
onChange={e => setSelectedSort(e.target.value)}
>
<MenuItem value="1">Sort</MenuItem>
<MenuItem value="device">Device</MenuItem>
<MenuItem value="customer">User</MenuItem>
<MenuItem value="server">Server</MenuItem>
<MenuItem value="creation">Creation date</MenuItem>
<MenuItem value="update">Update date</MenuItem>
</Select>
</FormControl>
</div>
<div>
<DeviceList
classes={classes}
deviceData={devices ? devices: props.data}
filtered={props.filtered}
/>
</div>
只需将sortDeviceData设置为selectedSort的函数,并将selectedSort传入:
const sortDeviceData = selectedSort => {...}
由于您的useEffect中未使用selectedSort,因此不会执行它。好的,可能我不太确定发生了什么。我想你是从道具数据中得到这些设备的吧 然后,您可以在设备的useState中使用props.data来省略第一个useEffect:
const [devices, setDevices] = useState(props.data)
然后,当您更改排序顺序时,不应该更新props.data inplace-props应该是只读的
我个人会编写一个函数,在给定selectedSort的情况下返回比较器:
const comparator = selector => {
switch (selector) {
case „1“: return (a,b)=>...
...
}
}
然后呢
useEffect(() => setDevices(devices.sort(comparator(selectedSort)))
, [selectedSort])
您的刷新会异步更改道具,因此在useEffect props.data中仍然为null或任何初始值。 然后,当从refresh中的已解析承诺设置props.data时,将重新提交组件。但由于设备保持不变,useEffect不会再次执行,并且设备将永远不会被设置为props.data中的新值 我建议您决定是否由父级控制获取数据,然后您可以将设备传递到此组件,或者此组件进行获取,然后您可以在useEffect中使用此组件中的状态设置器刷新替换setData中的代码:
useEffect(() => {
fetch(....
.then(json => setDevices(json.devices)
}, [])
这将在第一次渲染时运行一次,并在数据触发器到达时使用设备重新渲染
为了避免使用devices.sort不是一个函数,请添加一个保护:如果设备…您正在获取子设备中的数据,这将在父设备中设置状态。您可以将其作为数据传递给您的孩子。但是,然后在useffect中调用refresh,这是异步的,因此您需要再次设置旧的props.data 在刷新的子对象中删除useEffect,并使用props.data作为设备useState的初始道具 可以删除仪表板的刷新属性
您的家长控制数据获取,因此请依靠家长来完成。我认为最好使用switch。。。如果条件大于多个,请尝试将“选择”中的属性值更改为默认值,然后重试check@AkhilAravind,关于switch,实际上是真的,我忘了我可以用它了,我已经重写了它来切换,关于defaultValue,它不起作用,你有一个同样的stackblitz示例吗,您对selectedSort使用的是什么软件包?但在useEffect中,我使用selectedSort作为一个需要观察的参数,因此如果selectedSort发生更改,useEffect应该会看到它并进行更新。将selectedSort作为一个参数传递会使它完全不起作用。不幸的是,编辑您的帖子时,它不想添加道具。刷新并单击您的帖子而不是我的。。。不管怎么说,问题可能出在其他地方>我的意思是,当我试图按照你的方式做时,它说device.sort不是一个函数,问题是const[devices,setDevices]=useStateprops.data不会更新设备,它总是空的,同样我以前的useffects似乎也不会对设备的状态产生任何影响。只有在我点击Select two Times中的一些值之后,它才会改变如果我没有错,我按照你说的做了所有这些,我获取它并在componentDidMount瞬间启动它,使用useEffect,然后数据应该被获取并通过道具传递给子组件,由于此时子组件应该通过排序函数更改数据,并基于更改初始化刷新函数。我编辑了我的问题,以澄清我的代码中发生的一切。它起作用了!最后我把你所有的想法都弄混了,加了一点我自己的想法,效果很好,现在我必须清理一个代码,因为我弄乱了一些东西,但最重要的是,这个目标已经实现,现在只是在润色代码:非常感谢你的帮助!