React Context with Hooks 总是“落后一步”

Posted

技术标签:

【中文标题】React Context with Hooks 总是“落后一步”【英文标题】:React Context with Hooks is always "one step behind" 【发布时间】:2020-07-08 08:37:46 【问题描述】:

我正在编写一个计算机比较网站,在为 API 调用设置过滤器时遇到了问题。添加过滤器时,它似乎总是“落后一步”。例如,我为“orderby”添加了过滤器,然后调用getComputers(),它使用过滤器作为参数从我们的 api 获取 pcs,但它不应用任何参数,因为过滤器仍然是空的。如果我为“orderby”使用不同的值再次执行此操作,它会将之前的值作为 api 调用的参数。我不明白为什么会这样工作,并且非常感谢任何帮助:)

是的,我之前对此进行过研究,但似乎没有什么对我有用...

这是我的代码:

搜索结果页面:

import React from 'react';
import  useContext  from 'react';
import SearchContext from '../../context/search/SearchContext';
import Navbar from '../layout/Navbar';
import Computers from '../computer/Computers';
import Select from 'react-select';

const SearchResults = () => 
  const searchContext = useContext(SearchContext);
  const  filters, orders, getComputers, addFilter  = searchContext;

  return (
    <>
      <Navbar activeItem='Search'></Navbar>

      <div className='container my-3 text-dark'>
        <div className='row'>
          <div className='col-lg-9 col-md-6'>
            <h1 className='display-3 mt-3'>Suche</h1>
          </div>
          <div className='col-lg-3 col-md-6'>
            <Select
              placeholder='Sortierung'
              options=orders.map(order => 
                return  value: order.value, label: order.trans ;
              )
              onChange=val => 
                addFilter( name: 'orderby', value: val.value );
                getComputers();
              
            />
          </div>
        </div>
        <div className='my-3'>
          filters.map((filter, index) => 
            var text = filter.value.toString();
            return (
              <span
                className='badge badge-pill badge-secondary mx-1 p-2'
                key=index
              >
                text.charAt(0).toUpperCase() + text.slice(1)
              </span>
            );
          )
        </div>

        <Computers></Computers>
      </div>
    </>
  );
;

export default SearchResults;

奇怪的是,我的页面在小药丸中正确显示了当前的“orderby”过滤器(见第 42 行)。但是 API 调用没有采用正确的过滤器...

我的上下文的相关部分:

SearchState.js:

const [state, dispatch] = useReducer(SearchReducer, initialState);

// ACTIONS

  // Add filter
  const addFilter = filter => 
    console.log(state.filters);
    dispatch( type: ADD_FILTER, payload: filter );
  ;

// Get PCs from API
  const getComputers = async () => 
    try 
      state.loading = true;
      console.log(state.filters);
      let params = ;
      state.filters.forEach(filter => 
        // if (filter.name !== 'usecase' && filter.name !== 'type')
        //only as long as usecase and type are not implemented in api yet
        if (!params[filter.name]) params[filter.name] = '';
        params[filter.name] = filter.value;
      );
      console.log(params);
      const res = await axios.get(
        'notgonnatellumyurlxd',
        
          params
        
      );
      console.log(res);
      dispatch( type: GET_COMPUTERS, payload: res.data );
     catch (err) 
      console.log(err);
    
  ;

SearchReducer.js:

export default (state, action) => 
  switch (action.type) 
    case ADD_FILTER:
      // Used for deciding whether to update existing filter or set new
      var update = false;
      state.filters.forEach(filter => 
        if (filter.name === action.payload.name) 
          update = true;
        
      );
      return 
        ...state,
        filters: !update
          ? [...state.filters, action.payload]
          : state.filters.map(filter =>
              filter.name === action.payload.name ? action.payload : filter
            )
      ;
.
.
.
case GET_COMPUTERS:
      return 
        ...state,
        computers: action.payload,
        loading: false
      ;
;

我现在真的很挣扎,希望在这里找到一些帮助。提前非常感谢!你们这里的人很棒:)

【问题讨论】:

你能用 Context 和 Context.Provider 在codesandbox 上创建简单的例子(而不是复制你的整个应用程序)吗?我想看看这个问题,但需要在各种操作期间记录值。 感谢您的努力,但问题已经得到解答:) 【参考方案1】:

getComputers 适用于其他 state "instance"/ref`

您可以使用useEffect 作为addFilter 更改filter

useEffect(() => 
  getComputers();
, [filter]);

onChange=val => addFilter( name: 'orderby', value: val.value )

addFilter更改filter ... filter更改运行效果代码(每次更改)

【讨论】:

谢谢!按预期工作!不知道 React 会为不同的操作创建不同的状态“分支”......感谢您的出色回答 :) 它类似于 setState 行为......你不能期望在命令之后更新(没有回调)

以上是关于React Context with Hooks 总是“落后一步”的主要内容,如果未能解决你的问题,请参考以下文章

如何将 React Context 与 Hooks 一起使用?

Make React Easy With These 5 Custom React Hooks

React 系列 02❤️ Custom Hooks 中使用 React Context

在 React with React Hooks 上使用动态导入视频

如何在 React with Typescript 中使用和指定通用 Hooks?

React Context 和 Hooks API 的酶错误