我知道React Hooks
不支持异步方法,例如async / await。
仅当setState of the hooks
同步并且值成功存储后,我才需要处理下一个过程。
对于原始的this.setState({..})
,我使用回调函数执行以下操作,但是我该怎么做hooks setState
?
例如
export const FirstComponent = () => {
const [peopleList, setPeopleList] = useState(null)
const [myList, setMyList] = useState(null)
const { data, loading, error } = useQuery(gql(GQL_GET_PEOPLE_LIST)
useEffect(() => {
const onCompleted = data => {
setPeopleList(data.list)
}
if (!loading) {
onCompleted(data)
}
}, [data, loading, error])
...
const onChangeMyList = id => {
setMyList(peopleList.filter(x => x.id === id)
.map(x => x.item.originalList.lists) // <- This must be completed first!!
openModal(true) // <- Then, it has to be executed!
}
...
return (
<div>
<p onClick={() => onChangeMyList(id)}>Click!</p>
<div>
)
}
我应该如何解决?
答案 0 :(得分:0)
解决这个问题的一种方法是这样的:
const [modalOpen, setModalOpen] = useState(false)
useEffect(() => { if (modalOpen) openModal(true); }, [modalOpen]);
然后不调用openModal(true),而是调用setModalOpen(true);
答案 1 :(得分:0)
在这种情况下,您甚至不需要useEffect()
。
由于您在更改列表时位于事件处理程序onClick={() => onChangeMyList(id)}
中,因此默认情况下,React将自动批处理所有setState()
调用更新。这意味着当所有状态都已更新时,将进行下一个渲染。我不知道您如何打开模态,但是您可以执行以下操作:
function App() {
const [myList, setMyList] = React.useState(['a','b','c']);
const [openModal, setOpenModal] = React.useState(false);
function handleClick() {
setMyList(['a','b','c','d','e','f']);
setOpenModal(true);
}
return(
<React.Fragment>
<div><b>myList: </b>{myList}</div>
<button onClick={handleClick}>Click to change list and open modal</button>
{openModal &&
<div><b>I am Modal.</b> I was rendered together with the list: {myList}</div>
}
</React.Fragment>
);
}
ReactDOM.render(<App/>, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.3/umd/react-dom.production.min.js"></script>
<div id="root"/>