簡體   English   中英

當 state 第一次更改時,從 useEffect 無限調用回調

[英]Infinite calls to the callback from useEffect when the state changes for the first time

我有一個父組件將回調 function 傳遞給子組件,這樣每當子組件中數組的 state 發生變化時,都會調用回調。 出於某種原因,每當我第一次更改子組件中的 state 時,它都會導致無限循環,其中回調會永遠被調用。

這是下面的真實代碼。

當用戶在列表中添加新書時,我已經定義了一個突變來設置similarBooks 的列表。 子組件跟蹤列表。 SimilarBooks 的初始值由父組件提供。 子組件有一個表單可以將書籍添加到similarBooks 列表中。 每當該列表的 state 發生變化時,子組件中的 useEffect 就會被調用,然后調用父組件 function 提供的回調 function。 回調 function 執行 setSimilarBooks 突變。

一件有趣的事情是,如果我只是將 onChangeSimilarBooks 回調移動到 Child 組件中,那么問題就不再存在了。 或者,如果我將回調保留在父級中,但不調用 setSimilarBooks 突變,那么問題也會消失。

父組件:

const [setSimilarBooks, { data: mutationSimilarBooksData, 
      loading: mutationSimilarBooksLoading, error: mutationSimilarBooksError }] 
         = useMutation(setSimilarBooksMutation);
const onChangeSimilarBooks = (values) => {
    console.log(values);
    if (!mutationSimilarBooksLoading) {
        setSimilarBooks({
            variables: {
                bookId: bookId,
                similarBooksIds: values.map(value => value.id),
            },
        });
    }
}

Parent 有一個子組件:

<ChipsComponent
                key="{bookDetails.book.name}_similarbooks"
                initialValues={bookDetails.book.similarBooks}
                suggestions={booksList.books}
                allowNew={false}
                onChangeCallback={onChangeSimilarBooks}
                userFriendlyValue={userFriendlyValueOfBook}
            />

子組件:

const [values, setValues] = useState(initialValues);
useEffect(() => {
    onChangeCallback(values);
}, [values]);

...


...

return (
    <div className="container">
        {values.map((book, index) => (
            <div className="books" key={index}>
                {userFriendlyValue(book)}
                <button onClick={() => deleteTag(index)}>x</button>
            </div>
        ))}
        <div className="newTag">
            <input
                value={input}
                placeholder="Enter a tag"
                onKeyDown={onKeyDown}
                onKeyUp={onKeyUp}
                onChange={onChange}
            />
            {suggestionsActive && <Autocomplete />}
        </div>

    </div>);

我希望每次 state 真正改變時只調用一次回調。

參考 function onChangeSimilarBook更改每個渲染。 您以某種方式通過引用使其穩定。 您可以嘗試使用useEvent

使用事件.md

很明顯,為什么將回調和useMutation掛鈎移動到子級並直接調用setSimilarBooks ,或者將回調保留在父級而不調用setSimilarBooks會觸發此問題。 我從代碼中看到的唯一可能性是onChangeSimilarBooks回調不是一個穩定的參考。 您可以將其包裝在useCallback掛鈎中以記憶它。

例子:

const onChangeSimilarBooks = useCallback((values) => {
  console.log(values);
  if (!mutationSimilarBooksLoading) {
    setSimilarBooks({
      variables: {
        bookId,
        similarBooksIds: values.map(value => value.id),
      },
    });
  }
}, [mutationSimilarBooksLoading, setSimilarBooks]);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM