使用 useState 通过单击按钮来响应更新状态
React update state with button click using useState
任何人都可以向我解释 "right" 解决以下问题的方法。我有这个包含事件数据的简单页面。最初这是上周的数据,但页面上有一个按钮可以将数据设置为全部。我使用 useEffect() 到 loadData() 并最初设置 all=false。当我单击按钮时,我想将所有更新为 true 并将数据更新为所有数据。
下面的代码有效,但有点奇怪,因为我首先必须获取 !all 的数据,然后我设置 all=true,但随后它再次重新呈现。
有什么好的方法吗?我试着把 "onClick" 代码反过来,所以:setAll(!all);loadData(all),但这不起作用,因为状态没有立即更新。
任何 help/tips 都会很棒!!
const Events = ({auth}) => {
const [data, setEventData] = useState([])
const [all, setAll] = useState(false)
const loadData = async (givenScope) => {
const scope = (givenScope ? '' : '?scope=last_week')
const eventdata = await makeAPICall('/api/events' + scope, 'GET', null, await auth.getAccessToken())
setEventData(eventdata);
}
useEffect(() => {
loadData(all);
}, [])
const columns = [{
Header: 'Datum/tijd',
accessor: 'datetime',
Cell: props => <Moment date={props.value} tz="Europe/Amsterdam" format="YYYY-MM-DD HH:mm"/>
}, {
Header: 'Event',
accessor: 'value',
}]
return <div><Button onClick={() => {loadData(!all);setAll(!all)}}>{all ? 'Last week' : 'All'}</Button> <DefaultTable data={data} columns={columns} loading={data.length > 0 ? false : true} /></div>
}
处理上述代码的一个相对简单的方法是将 all
作为值传递给 useEffect
的依赖数组,这样您就不必担心 loadData
在状态之后执行更新
const Events = ({auth}) => {
const [data, setEventData] = useState([])
const [all, setAll] = useState(false)
const loadData = async (givenScope) => {
const scope = (givenScope ? '' : '?scope=last_week')
const eventdata = await makeAPICall('/api/events' + scope, 'GET', null, await auth.getAccessToken())
setEventData(eventdata);
}
useEffect(() => {
loadData(all);
}, [all])
const columns = [{
Header: 'Datum/tijd',
accessor: 'datetime',
Cell: props => <Moment date={props.value} tz="Europe/Amsterdam" format="YYYY-MM-DD HH:mm"/>
}, {
Header: 'Event',
accessor: 'value',
}]
return <div><Button onClick={() => {setAll(all => !all)}}>{all ? 'Last week' : 'All'}</Button> <DefaultTable data={data} columns={columns} loading={data.length > 0 ? false : true} /></div>
}
并且在任何情况下,您的代码都将呈现两次,因为数据是异步可用的。为了改善用户体验,您可以在获取数据时显示加载器。
您可以在按钮的 onClick
:
上尝试类似的操作
<Button
onClick={ () => {
setAll((prevState) => {
loadData(!prevState); // This will load the data during the state update
return !prevState;
}
}}
/>
任何人都可以向我解释 "right" 解决以下问题的方法。我有这个包含事件数据的简单页面。最初这是上周的数据,但页面上有一个按钮可以将数据设置为全部。我使用 useEffect() 到 loadData() 并最初设置 all=false。当我单击按钮时,我想将所有更新为 true 并将数据更新为所有数据。
下面的代码有效,但有点奇怪,因为我首先必须获取 !all 的数据,然后我设置 all=true,但随后它再次重新呈现。
有什么好的方法吗?我试着把 "onClick" 代码反过来,所以:setAll(!all);loadData(all),但这不起作用,因为状态没有立即更新。
任何 help/tips 都会很棒!!
const Events = ({auth}) => {
const [data, setEventData] = useState([])
const [all, setAll] = useState(false)
const loadData = async (givenScope) => {
const scope = (givenScope ? '' : '?scope=last_week')
const eventdata = await makeAPICall('/api/events' + scope, 'GET', null, await auth.getAccessToken())
setEventData(eventdata);
}
useEffect(() => {
loadData(all);
}, [])
const columns = [{
Header: 'Datum/tijd',
accessor: 'datetime',
Cell: props => <Moment date={props.value} tz="Europe/Amsterdam" format="YYYY-MM-DD HH:mm"/>
}, {
Header: 'Event',
accessor: 'value',
}]
return <div><Button onClick={() => {loadData(!all);setAll(!all)}}>{all ? 'Last week' : 'All'}</Button> <DefaultTable data={data} columns={columns} loading={data.length > 0 ? false : true} /></div>
}
处理上述代码的一个相对简单的方法是将 all
作为值传递给 useEffect
的依赖数组,这样您就不必担心 loadData
在状态之后执行更新
const Events = ({auth}) => {
const [data, setEventData] = useState([])
const [all, setAll] = useState(false)
const loadData = async (givenScope) => {
const scope = (givenScope ? '' : '?scope=last_week')
const eventdata = await makeAPICall('/api/events' + scope, 'GET', null, await auth.getAccessToken())
setEventData(eventdata);
}
useEffect(() => {
loadData(all);
}, [all])
const columns = [{
Header: 'Datum/tijd',
accessor: 'datetime',
Cell: props => <Moment date={props.value} tz="Europe/Amsterdam" format="YYYY-MM-DD HH:mm"/>
}, {
Header: 'Event',
accessor: 'value',
}]
return <div><Button onClick={() => {setAll(all => !all)}}>{all ? 'Last week' : 'All'}</Button> <DefaultTable data={data} columns={columns} loading={data.length > 0 ? false : true} /></div>
}
并且在任何情况下,您的代码都将呈现两次,因为数据是异步可用的。为了改善用户体验,您可以在获取数据时显示加载器。
您可以在按钮的 onClick
:
<Button
onClick={ () => {
setAll((prevState) => {
loadData(!prevState); // This will load the data during the state update
return !prevState;
}
}}
/>