Может кто-нибудь объяснить мне, что «правильный» способ сделать нижеприведенную проблему. У меня есть эта простая страница с данными о событиях. Первоначально это данные за последнюю неделю, но на странице есть кнопка, которая устанавливает данные для всех. Я использую useEffect () для loadData () с установкой all = false изначально. Когда я нажимаю кнопку, я хочу обновить все до true и данные для всех данных.

Приведенный ниже код работает, но это несколько странно, потому что сначала я должен получить данные для! All, а после этого я установил all = true, но затем он повторяется.

Есть ли хороший способ сделать это? Я попытался поместить код "onClick" наоборот, так: setAll (! All); loadData (all), но это не работает, потому что состояние не обновляется немедленно.

Любая помощь / советы будут великолепны!

 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>

}
2
Eric Jansen 16 Апр 2019 в 09:55

2 ответа

Лучший ответ

Относительно простым способом обработки вышеуказанного кода было бы передать 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>

}

И в любом случае ваш код будет отображаться дважды, поскольку данные доступны асинхронно. Для улучшения пользовательского опыта вы можете показать загрузчик во время выборки данных.

2
Shubham Khatri 16 Апр 2019 в 07:04

Вы можете попробовать что-то вроде этого на кнопке onClick:

<Button 
  onClick={ () => {
    setAll((prevState) => {
      loadData(!prevState);    // This will load the data during the state update
      return !prevState;
    }
  }}
/>
0
cbdeveloper 16 Апр 2019 в 07:15