简体   繁体   English

State 未使用 useState 挂钩设置 | ReactJS

[英]State not getting set using useState hook | ReactJS

I have a component where I am storing API response in responseArray and I am using this responseArray to initialize matchFundResults state using hooks.我有一个组件,我在responseArray中存储 API 响应,并且我正在使用这个responseArray使用钩子初始化matchFundResults state。 Next, I am trying to run a useEffect using matchFundResults as a dependency but matchFundResults is always coming as blank whereas I have value in responseArray .接下来,我尝试使用matchFundResults作为依赖项来运行 useEffect,但matchFundResults始终为空白,而我在responseArray中有值。 How should this be fixed?这应该如何解决?

const MatchFundModal = ({ row, val }) => {
  let rightBody;
  const dispatch = useDispatch();
  const selectedRows = useSelector((state) => state.pcPerformance.processor.checkedRows.selectedRows || []);
  const responseArray = useSelector((state) => state.pcPerformance.processor.fundAliases);
  const [showMatchFundModal, setshowMatchFundModal] = useState(val);
  const [matchFundResults, setMatchFundResults] = useState(responseArray);
  
  const [activeRowData, setActiveRowData] = useState({ Id: null, FundName: null, SourceId: null });
  
  const [selectedMatchFund, setSelectedMatchFund] = useState();
  const [searchFieldVal, setSearchFieldVal] = useState();

  if (!activeRowData.Id) {
    const firstRow = selectedRows.length > 0 && selectedRows[0];
    setActiveRowData({ Id: firstRow.Id, FundName: firstRow.FundName, SourceId: firstRow.SourceId });
    //dispatch(getFundNameAliasMatch(firstRow.FundName, firstRow.SourceId));
  }
  useEffect(() => {
    dispatch(getFundNameAliasMatch(activeRowData.FundName, activeRowData.SourceId));
  }, [activeRowData.Id]);
  
  console.log('Helloworld responseArray', responseArray);
  console.log('Helloworld matchFundResults', matchFundResults);
  useEffect(() => {
    rightBody = matchFundResults**.map((item) => {
      return (
        <li key={item.FundId}>
          <input
            type="radio"
            value={item.FundId}
            name="action-radio"
            id={`action-radio-${item.FundId}-${item.SourceId}`}
            onClick={(e) => handleRadioButtonClick(e)}
          />
          <span>{item.FundName}</span>
          <br />
          <span className="searchFundID">#{item.FundId}</span>
        </li>
      );
    });
  }, [matchFundResults, activeRowData.Id]);

  const matchFundBody = (
    <div className="matchFundModal grid">
      <p className="matchFundModal__header 12">Match or add</p>
      <div className="matchFundModal__body 12">
        <div className="matchFundModal__body__right 6">
          <p id="possibleMatchText">Possible matches</p>
          <ul>{rightBody}</ul>
        </div>
      </div>
      <div className="matchFundModal__footer 12">
        <button className="matchFundModal__footer__button">Match Selected</button>
      </div>
    </div>
  );
  return (
    <Fragment>
      <Modal
        isOpen={showMatchFundModal}
        bodyContent={matchFundBody}
        showHeader={false}
        handleOnModalToggleFunction={hideModal}
        handleOnModalPrimaryButtonClick={onPrimaryButtonClick}
        handleOnModalSecondaryButtonClick={hideModal}
        primaryButtonText={'Match Fund'}
        centered={true}
        size="sm"
        hideFooterButtons={true}
        modalClasses="matchFundModal"
        showFooter={false}
      />
    </Fragment>
  );
};

export default MatchFundModal;```
[![enter image description here][1]][1]


  [1]: https://i.stack.imgur.com/HxIv4.png

I don't know why you would want to copy responseArray to matchFundResults instead of just using responseArray directly but you never use setMatchFundResults when responseArray changes so you only set it initially and at that time responseArray is probably an empty array.我不知道您为什么要将 responseArray 复制到 matchFundResults 而不是直接使用 responseArray 但是当 responseArray 更改时您从不使用 setMatchFundResults 所以您只在最初设置它,当时 responseArray 可能是一个空数组。 You could do the following:您可以执行以下操作:

const responseArray = useSelector((state) =>
  state.pcPerformance.processor.fundAliases);
const [matchFundResults, setMatchFundResults] = useState(responseArray);
//every time responseArray changes you need to set matchFundResults
useEffect(()=>setMatchFundResults(responseArray),[responseArray])

But it probably would be better to not copy redux state to local state and instead just use redux state directly. But it probably would be better to not copy redux state to local state and instead just use redux state directly.

Your comment suggest you have all data in redux state and would like to filter the data (the reason why you copy redux state to local state).您的评论建议您在redux Z9ED39E2EA9E2EA931586B6A9942EF573EZ中拥有所有数据You could do that with selectors in the following way:您可以通过以下方式使用选择器来做到这一点:

 const { Provider, useSelector } = ReactRedux; const { createStore } = Redux; const { createSelector } = Reselect; const { useState, useMemo } = React; const initialState = { data: [ 'hello world', 'hello redux', 'hello react', 'goodbye jquery', ], }; const reducer = (state) => state; //selectors const selectData = (state) => state.data; const createSelectFilteredData = (filter) => createSelector([selectData], (data) => data.filter((item) => item.toLowerCase().includes(filter.toLowerCase()) ) ); //creating store with redux dev tools const store = createStore(reducer, initialState); const App = () => { const [filter, setFilter] = useState(''); const selectFilteredData = useMemo( () => createSelectFilteredData(filter), [filter] ); const filteredData = useSelector(selectFilteredData); return ( <div> <label> filter: <input type="text" value={filter} onChange={(e) => setFilter(e.target.value)} /> </label> <div> filtered data: <pre> {JSON.stringify(filteredData, undefined, 2)} </pre> </div> </div> ); }; ReactDOM.render( <Provider store={store}> <App /> </Provider>, document.getElementById('root') );
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/redux/4.0.5/redux.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-redux/7.2.0/react-redux.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/reselect/4.0.0/reselect.min.js"></script> <div id="root"></div>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM