reactjs useEffect未正确跟踪useState依赖项

vbopmzt1  于 2022-12-22  发布在  React
关注(0)|答案(3)|浏览(178)

我有一个按钮和一个输入框,提交输入后,将对searchTerm运行搜索并显示结果表。(),以便仅在searchTerm更改时才运行搜索。()在窗口打开时运行,我添加了一个检查,查看searchTerm是否〉0,以便在窗口打开时不执行搜索。
但是,这样做后,表行不会在第一次搜索时更新,而是在第二次搜索时更新。如果我删除if (searchTerm.length > 0)检查,表将在第一次搜索时按预期填充(尽管它将立即对空searchTerm运行搜索,这并不理想)。

export const SearchWindow: React.FC<Props> = props => {

    const documentationIndexState = useSelector((store: StoreState) => store.documentationIndex);
    const dispatch = useDispatch();
    const [searchInput, setSearchInput] = React.useState(''); // value inside input box
    const [searchTerm, setSearchTerm] = React.useState(''); // term to search (set once search clicked)

    React.useEffect(() => {
        console.log('in useEffect with searchTerm len: ' + searchTerm.length);
        if (searchTerm.length > 0) {
            console.log('len > 0, running search');
            getSearchResults(props.config, searchTerm, documentationIndexState, dispatch).then(async searchResults => {
                const rows = searchResults.map(result => {
                    return {
                        cells: {
                            source: documentationIndexState.headerReference.find(x => x.id === result.id)!.source,
                        },
                    };
                });
                dispatch(setSearchResults(rows));
            });
        }
    }, [searchTerm]); // Only run search if searchTerm changes

    return (
        <div>
            <form>
                <input
                    placeholder='Enter Search Term'
                    onChange={e => setSearchInput(e.target.value)}
                    value={searchInput}
                />
                <button
                    onClick={e => {
                        e.preventDefault();
                        setSearchTerm(searchInput);
                    }}
                >
                    Search
                </button>
            </form>
        </div>
        <DataTable
            rows={documentationIndexState.searchResults}
        />
        ...
m1m5dgzv

m1m5dgzv1#

搜索按钮的回调应该执行搜索。

function Form() {
  const [searchInput, setSearchInput] = React.useState('');
  const runSearch = React.useCallback(
    () => {
      console.info('Searching', searchInput)
    },
    [searchInput]
  );

  return (
    <form>
      <h1> The form! </h1>
      <input
        placeholder='Enter Search Term'
        onChange={e => setSearchInput(e.target.value)}
      />
      <button
        type="button"
        onClick={runSearch}
      >
        Search
      </button>
    </form>
  );
}
ReactDOM.createRoot(
    document.getElementById('app')
).render(
    React.createElement(Form)
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.1.0/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.1.0/umd/react-dom.development.js"></script>

<div id="app">
</div>
bnl4lu3b

bnl4lu3b2#

这就是你想要达到的目的吗

const [loaded, setLoaded] = React.useState(false);
React.useEffect(() => {
    if (!loaded) {
        setLoaded(true);
        return;
    }
    console.log('in useEffect with searchTerm len: ' + searchTerm.length);
    if (searchTerm.length > 0) {
        console.log('len > 0, running search');
        getSearchResults(props.config, searchTerm, documentationIndexState, dispatch).then(async searchResults => {
            const rows = searchResults.map(result => {
                return {
                    cells: {
                        source: documentationIndexState.headerReference.find(x => x.id === result.id)!.source,
                    },
                };
            });
            dispatch(setSearchResults(rows));
        });
    }
}, [searchTerm]); // Only run search if searchTerm changes & loaded is true
flvlnr44

flvlnr443#

最后在getSearchResults()方法内部添加了一个if (searchTerm.length === 0)检查,并让它返回[] if true,而不是在进入搜索方法之前检查len。

相关问题