首页 > 解决方案 > ReactJs hook 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: [], 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 带回被过滤掉的原始数据?

标签: javascriptarraysreactjsreact-hooksreducers

解决方案


这里最好的方法是不要在你的 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>
  );
}

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


推荐阅读