简体   繁体   中英

ReactJs hook reducer filtering through array based off user string input

I'm able to filter out the data that does not belong but when the user deletes what they have typed, the data that was filtered out does not come back. What is the best practice bring back the filtered values of the array?

 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 to bring back the original data that was filtered out?

The best approach here would not to filter the users data in your reducer. You should see your reducer as your database, and have a selector function, as your query. I'll add the filter key to the reducer, then, compute the filtered users in a variable.

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>
  );
}

This way, you will always keep your users safe in your reducer, and be able to filter too.

Just put the state.users.filter(...) code in the render function and use a conditional to filter the users.

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

  return (
    ...
    {filteredUsers}
    ...
  )

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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