【问题标题】:ReactJs hook reducer filtering through array based off user string inputReactJs hook reducer 通过基于用户字符串输入的数组进行过滤
【发布时间】:2020-10-29 13:56:11
【问题描述】:

我能够过滤掉不属于的数据,但是当用户删除他们输入的内容时,被过滤掉的数据不会回来。带回数组的过滤值的最佳做法是什么?

import React, { useReducer } from "react";
import "./styles.css";

const USER_UPDATE = "USER_UPDATE";
const ADD_USER = "ADD_USER";
const REMOVE_USER = "REMOVE_USER";
const FILTER_USER = "FILTER_USER";

const initState = { users: [], user: "" };

const reducer = (state, action) => {
  switch (action.type) {
    case FILTER_USER:
      return {
        ...state,
        users: state.users.filter(
          user =>
            user.toLowerCase().indexOf(action.payload.toLowerCase()) !== -1
        )
      };
    default:
      return state;
  }
};

export default function App() {
  const [state, dispatch] = useReducer(reducer, initState);
  const userUpdate = e => {
    const { value } = e.target;
    dispatch({ type: USER_UPDATE, payload: value });
  };
  const addNewUser = () => dispatch({ type: ADD_USER });
  const removeUser = i => dispatch({ type: REMOVE_USER, payload: i });
  const handleFilter = e =>
    dispatch({ type: FILTER_USER, payload: e.target.value });
  const renderUsers = state.users.map((user, i) => (
    <li
      key={i}
    >
      <button
        onClick={() => removeUser(i)}
      >
        x
      </button>
      <p style={{}}>{user}</p>
    </li>
  ));
  return (
    <div className="App">
      <pre>{state.user}</pre>
      <input placeholder="Enter a name" onChange={userUpdate} />
      <button onClick={addNewUser}>Add</button>
      <hr />
      <input placeholder="Filter name" onChange={handleFilter} />
      <ul style={{ listStyle: "none" }}>{renderUsers}</ul>
    </div>
  );
}

e 带回被过滤掉的原始数据?

【问题讨论】:

    标签: javascript arrays reactjs react-hooks reducers


    【解决方案1】:

    这里最好的方法是不要在你的 reducer 中过滤用户数据。您应该将 reducer 视为您的数据库,并有一个 selector 函数作为您的查询。我将filter 键添加到reducer,然后在变量中计算过滤后的用户。

    import React, { useReducer } from "react";
    import "./styles.css";
    
    const USER_UPDATE = "USER_UPDATE";
    const ADD_USER = "ADD_USER";
    const REMOVE_USER = "REMOVE_USER";
    const FILTER_USER = "FILTER_USER";
    
    const initState = { users: [], filter: "", user: "" };
    
    const reducer = (state, action) => {
      switch (action.type) {
        case FILTER_USER:
          return {
            ...state,
            filter: action.payload, // we'll just update the filter key
          };
        default:
          return state;
      }
    };
    
    export default function App() {
      const [state, dispatch] = useReducer(reducer, initState);
      const filteredUsers = state.users.filter(
              user =>
                state.filter === "" || user.toLowerCase().indexOf(state.filter.toLowerCase()) !== -1 // we filter our users by our string, or if it's empty, we'll return it.
            )
      }
    
      const userUpdate = e => {
        const { value } = e.target;
        dispatch({ type: USER_UPDATE, payload: value });
      };
      const 
      const addNewUser = () => dispatch({ type: ADD_USER });
      const removeUser = i => dispatch({ type: REMOVE_USER, payload: i });
      const handleFilter = e =>
        dispatch({ type: FILTER_USER, payload: e.target.value });
      const renderUsers = filteredUsers.map((user, i) => (
        <li
          key={i}
        >
          <button
            onClick={() => removeUser(i)}
          >
            x
          </button>
          <p style={{}}>{user}</p>
        </li>
      ));
      return (
        <div className="App">
          <pre>{state.user}</pre>
          <input placeholder="Enter a name" onChange={userUpdate} />
          <button onClick={addNewUser}>Add</button>
          <hr />
          <input placeholder="Filter name" onChange={handleFilter} />
          <ul style={{ listStyle: "none" }}>{renderUsers}</ul>
        </div>
      );
    }
    

    这样,您将始终确保用户在减速器中的安全,并且也能够进行过滤。

    【讨论】:

    • 非常感谢您向我解释我应该如何查看我的减速器并回答我的问题。
    【解决方案2】:

    只需将state.users.filter(...) 代码放在渲染函数中,并使用条件过滤用户。

    export default function App() {
      ...
      
      const filteredUsers = state.filter 
        ? state.users.filter(user => user.includes(state.filter)) 
        : state.users;
      ...
    
      return (
        ...
        {filteredUsers}
        ...
      )
    
    }
    

    【讨论】:

    • 谢谢,非常感谢您提供的信息。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-07-04
    • 2016-07-24
    • 2023-04-02
    • 2018-03-19
    • 1970-01-01
    • 2022-06-10
    相关资源
    最近更新 更多