在 React 中使用 useReducer 钩子过滤列表?

Posted

技术标签:

【中文标题】在 React 中使用 useReducer 钩子过滤列表?【英文标题】:filter a list with useReducer hook in React? 【发布时间】:2022-01-17 02:29:10 【问题描述】:

我需要知道如何使用 useReducer 函数以列表的形式过滤对象。我希望它根据对象的进度工作。我是新人,我也需要映射一些东西吗?

const data = 
  title: "Title",
  lessons: [
    
      title: "Introduction",
      data: Lesson1,
      isComplete: false,
      progress: 0,
    ,
    
      title: "Section",
      data: Lesson2,
      isComplete: false,
      progress: 10,
    ,
    
      title: "Review",
      data: Lesson3,
      isComplete: false,
      progress: 0,
    ,
  ],
;
const [state, dispatch] = useReducer(reducer, data.lessons);

  function reducer(state, action) 
    switch (action.type) 
      case "all":
        return  ...state.filter((filterlesson) => filterlesson >= 0) ;
      case "viewed":
        return  ...state.filter((filterlesson) => filterlesson != 0) ;
      case "notviewed":
        return  ...state.filter((filterlesson) => filterlesson == 0) ;
      default:
        return state;
    
  
const Filter = () => 
    return (
      <>
        <div className=styles.filter>
          <button onClick=() => dispatch( type: "all" )>All</button>
          <button onClick=() => dispatch( type: "viewed" )>Viewed</button>
          <button onClick=() => dispatch( type: "notviewed" )>Not Viewed</button>
        </div>
      </>
    );
  ;
 
return (
    <Fragment>
        <Filter />
        state
    </Fragment>
  );

我之前尝试过,但认为应该使用 useReducer :

        data.lessons
            .filter((l) => l.progress === 0)
            .map((filterLesson, i) => (
              <li key=i></li>
            ))

【问题讨论】:

【参考方案1】:

不确定这是否是正确的方法,但这是我在没有 useReducer 的情况下提出的一种方法。欢迎任何优化!

const [filterState, setfilterState] = useState(data.lessons);

  const allLessons = useMemo(() => 
    return data.lessons.filter((less) => less.progress >= 0);
  );
  const viewedLessons = useMemo(() => 
    return data.lessons.filter((less) => less.progress != 0);
  );
  const notViewedLessons = useMemo(() => 
    return data.lessons.filter((less) => less.progress == 0);
  );
 const Filter = () => 
    return ( 
       <div >
          <button
            onclick=() => 
              setfilterState(allLessons);
            
          >
            All Lessons
          </button>
          <button
            onclick=() => 
              setfilterState(viewedLessons);
            
          >
            Viewed
          </button>
          <button size="1em" onclick=() => 
              setfilterState(notViewedLessons);
            
          >
            Not Viewed
          </button>
        </div>
)
;

 const List = () => 
    return (
      <Fragment>
        <div className=styles.list>
          filterState.map((item, i) => (
            <li key=i>item</li>
          ))
      </Fragment>
    );
  ;
return (
    <Fragment>
        <Filter />
        <List />
    </Fragment>
  );

【讨论】:

以上是关于在 React 中使用 useReducer 钩子过滤列表?的主要内容,如果未能解决你的问题,请参考以下文章

在表单控制输入中反应 js useReducer 钩子

使用带有 useReducer() 钩子的 React Context API 有啥优点和缺点?

页面刷新后 React useReducer 钩子状态丢失

React TS useContext useReducer 钩子

如何测试组件中的react useContext useReducer调度

如何在 useReducer 钩子中发出异步服务器请求?