Неужели не поддерживается асинхронное setState of React Hooks? - PullRequest
1 голос
/ 10 июля 2019

Я знаю, 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>
    )
}

Как мне это исправить?

Ответы [ 2 ]

0 голосов
/ 11 июля 2019

В этом случае вам даже не нужно 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"/>
0 голосов
/ 11 июля 2019

Один из способов решить эту проблему будет выглядеть так:

const [modalOpen, setModalOpen] = useState(false)
useEffect(() => { if (modalOpen) openModal(true); }, [modalOpen]);

И позже вместо вызова openModal (true) вы должны вызвать setModalOpen (true);

...