【问题标题】:Todo fetcher and Filter待办事项提取器和过滤器
【发布时间】:2022-01-29 09:38:42
【问题描述】:

我在根据复选框值过滤我的待办事项数据时遇到了困难。默认选中复选框,显示响应中的所有数据。当单独选中 Show Completed 时,它应该只显示已完成的项目,类似于 Show Incompleted 复选框。

export const Todo = () => {
  const [todo, setTodo] = useState([]);
  const [loading, setloading] = useState(false);

//获取的数据

  async function fetchData() {
    setloading(true);
    const data = await fetch("https://jsonplaceholder.typicode.com/todos ");
    let res = await data.json();
    res = res.splice(0, 20);
    setTodo(res);
    setloading(false);
  }

  useEffect(() => {
    fetchData();
  }, []);

//处理onChange

 const compCheck = (e) => {
   
  };
  const InCompCheck = (e) => {
      
  };
  return (
    <>
      {loading && (
        <h1>
          <Loader />
        </h1>
      )}
      {!loading && (
        <>

          <TodoItems todo={todo} loading={loading} />

          <div id="filter-holder">
            <label>Show Completed</label>
            <input
              id="completed-checkbox"
              type="checkbox"
              onChange={compCheck}
              checked                  //by default should be checked to show complete list
            />
            <br />

            <label>Show Incompleted</label>
            <input
              id="incompleted-checkbox"
              type="checkbox"
              onChange={InCompCheck}
              checked                   
            />
          </div>
        </>
      )}
    </>
  );
};

这是沙盒链接:https://codesandbox.io/s/todo-fetcher-and-filter-rci40?file=/src/Todo.js

【问题讨论】:

    标签: reactjs filter react-hooks onchange checkboxlist


    【解决方案1】:

    为两个复选框创建一个状态,在更改监听器上更新状态,然后根据复选框状态过滤待办事项数组。

    export const Todo = () => {
      const [todo, setTodo] = useState([]);
      const [loading, setloading] = useState(false);
      const [checked, setChecked] = useState({ complete: true, incomplete: true });
    
      async function fetchData() {
        setloading(true);
        const data = await fetch("https://jsonplaceholder.typicode.com/todos ");
        let res = await data.json();
        res = res.splice(0, 20);
        setTodo(res);
        setloading(false);
      }
    
      useEffect(() => {
        fetchData();
      }, []);
      
    
      const getFilteredTodo = () => {
        //if both are unchecked show nothing
        if (!checked.complete && !checked.incomplete) return [];
        return todo.filter((obj) => {
          //if both are checked show all todo
          if (checked.complete && checked.incomplete) return obj;
          
          //filter objects based on the `Show completed` checkbox state
          return checked.complete ? obj.completed: !obj.completed
        });
      };
    
      const compCheck = (e) => {
        setChecked((curr) => ({ ...curr, complete: e.target.checked }));
      };
      const InCompCheck = (e) => {
        setChecked((curr) => ({ ...curr, incomplete: e.target.checked }));
      };
    
      return (
        <>
          {loading && (
            <h1>
              <Loader />
            </h1>
          )}
          {!loading && (
            <>
              <TodoItems todo={getFilteredTodo()} loading={loading} />
    
              <div id="filter-holder">
                <label>Show Completed</label>
                <input
                  id="completed-checkbox"
                  type="checkbox"
                  onChange={compCheck}
                  checked={checked.complete}
                />
                <br />
    
                <label>Show Incompleted</label>
                <input
                  id="incompleted-checkbox"
                  type="checkbox"
                  onChange={InCompCheck}
                  checked={checked.incomplete}
                />
              </div>
            </>
          )}
        </>
      );
    };
    

    【讨论】:

      【解决方案2】:

      您需要做的第一件事是控制您的复选框值并存储在状态中。 然后写一个过滤函数,过滤掉原来的TODO列表。然后调用组件中的函数,使其在每次状态更新时自行执行,然后循环遍历其结果以呈现它。

      const filterTodos = (todos, showCompleted, showIncompleted) => {
        let filteredList = todos;
        if (!showCompleted)
          filteredList = filteredList.filter((todo) => !todo.completed);
        if (!showIncompleted)
          filteredList = filteredList.filter((todo) => todo.completed);
        return filteredList;
      };
      
      const TodoList = () => {
        const [todos, setTodos] = useState([]);
        const [loading, setLoading] = useState(true);
        //Set the initial values in state not in the input props
        const [showCompleted, setShowCompleted] = useState(true);
        const [showIncompleted, setShowIncompleted] = useState(true);
      
        const onCompletedChangeHandler = (e) => {
          setShowCompleted(e.target.checked);
        };
      
        const onInCompletedChangeHandler = (e) => {
          setShowIncompleted(e.target.checked);
        };
      
        useEffect(() => {
          async function fetchData() {
            setLoading(true);
            const data = await fetch("https://jsonplaceholder.typicode.com/todos ");
            let res = await data.json();
            res = res.splice(0, 20);
            setTodos(res);
            setLoading(false);
          }
          fetchData();
        }, []);
      
        return (
          <>
            {loading && (
              <h1>
                <Loader />
              </h1>
            )}
            {!loading && (
              <>
                <TodoItems
                  todo={filterTodos(todos, showCompleted, showIncompleted)}
                  loading={loading}
                />
      
                <div id="filter-holder">
                  <label>Show Completed</label>
                  <input
                    id="completed-checkbox"
                    type="checkbox"
                    onChange={onCompletedChangeHandler}
                    value={showCompleted}
                  />
                  <br />
      
                  <label>Show Incompleted</label>
                  <input
                    id="incompleted-checkbox"
                    type="checkbox"
                    onChange={onInCompletedChangeHandler}
                    value={showIncompleted}
                  />
                </div>
              </>
            )}
          </>
        );
      };
      
      

      【讨论】:

      • e.target.value 将是一个字符串,您不能像 filterTodos 函数中的布尔值那样比较该值。 if (!showCompleted) 是错误的,showCompleted 每次都是正确的。
      • 糟糕,它应该是 e.target.checked。我已经修好了谢谢!
      • 我修好了谢谢!!
      猜你喜欢
      • 2021-01-19
      • 2022-11-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-03
      • 2022-10-13
      • 1970-01-01
      相关资源
      最近更新 更多