【问题标题】:updating the Child Component based on search results in react-hooks functional components根据 react-hooks 功能组件中的搜索结果更新子组件
【发布时间】:2023-03-15 09:47:01
【问题描述】:

我有 react-App 和 redux 使用 react-hooks 功能组件,它正确呈现 子组件 中的导师列表。我在其中添加了一个搜索框和handlchange 函数来更新列表组件(子组件)。 handlechange 函数工作正常,并将newlist 分配给handlechange function 主体内部的filtered 变量,但是handlechange 函数之外的filtered 的值保持不变。所以更新的过滤变量未分配给TutorList ComponentTutors.jsx 组件如下:

import React, { useState, useEffect } from "react";
import { useDispatch, useSelector } from 'react-redux';
import { Link, useParams, useHistory } from 'react-router-dom';
import TutorList from "./TutorList";
import * as actions from "../_actions/tutorActions";
import { TextField, Button, FormControl, } from "@material-ui/core";

const initialFieldValues = {
  search: ""
}

const Tutors = (props) => {
  const [values, setValues] = useState(initialFieldValues)

  let history = useHistory()
  const dispatch = useDispatch();
  // getting of tutorlist
  let tutor = useSelector(state => state.tutor.list);
  // sorting of tutors on date
  let tutorList = tutor.sort((a, b) => b.updatedOn.localeCompare(a.updatedOn));

  useEffect(() => {
    dispatch(actions.fetchAll())
  }, [])

  console.log("tutorList:", tutorList)

  // Variable to hold the filtered list before putting into state

  let newList = [];
  let filtered = tutorList;
  //when filter changes from '' to something filtered should be updated with newlist

  function handleChange(e) {
    const { name, value } = e.target
    const fieldValue = { [name]: value }
    setValues({
      ...values,
      ...fieldValue
    })

    // If the search bar isn't empty
    if (values.search !== "") {
      // Use .filter() to determine which items should be displayed
      // based on the search terms
      newList = tutorList.filter(item => {
        // change current item to lowercase
        const lc = item.fullName.toLowerCase();
        // change search term to lowercase
        const filter = e.target.value.toLowerCase();
        console.log("filter", filter);
        // check to see if the current list item includes the search term
        // If it does, it will be added to newList. Using lowercase eliminates
        // issues with capitalization in search terms and search content
        return lc.includes(filter);
      });
    } else {
      newList = tutorList;
    }
    console.log("newList:", newList)//shows correct list
    filtered = newList
    console.log("filtered:", filtered)//shows correct value
  }

  return (
    <div>
      <br />
      <TextField
        name="search"
        variant="outlined"
        label="Search Tutor"
        paceholder="search tutor..."
        value={values.search}
        onChange={handleChange}
      />

      <TutorList
        tutorList={filtered}

      />

      <Button onClick={() => history.goBack()}
        size="small" variant="contained" color="secondary">
        back
       </Button>
    </div>
  );

}

export default Tutors;

TutorList 组件应根据在搜索字段中输入的过滤器显示新列表。任何一种解决方法或更好的解决方案的帮助。在此先感谢。

【问题讨论】:

    标签: javascript reactjs redux react-hooks


    【解决方案1】:

    无需更新从handleChange 过滤的newList。 React 不是这样工作的。你不会得到重新渲染。你在handleChange中唯一应该做的就是setValue

    const [textInputValue, setTextInputValue] = useState('');
        function handleChange(e) {
            setTextInputValue(e.target.value);
        }
    

    然后根据

    进行所有排序
    let tutor = useSelector(state => state.tutor.list)
    // and textInputValue
    

    此外,无需在状态中存储过滤后的值。

    【讨论】:

      【解决方案2】:

      创建一个新状态
      const Tutors =(props)=> {
          const [values, setValues] = useState(initialFieldValues)
          const [filtered, setFiltered] = useState(null)
      

      handleChange() 函数内部将filtered 设置为过滤元素的filtered

       function handleChange(e){
             //........
      
            console.log("newList:",newList)//shows correct list
            //filtered=newList  <= instead of this 
            setFiltered(newList) // <= do this
            console.log("filtered:",filtered)//shows correct value
          }
      

      最终的代码应该是这样的:

      import React, { useState, useEffect } from "react";
      import { useDispatch, useSelector } from "react-redux";
      import { Link, useParams, useHistory } from "react-router-dom";
      import TutorList from "./TutorList";
      import * as actions from "../_actions/tutorActions";
      import { TextField, Button, FormControl } from "@material-ui/core";
      
      const initialFieldValues = {
        search: "",
      };
      
      const Tutors = (props) => {
        const [values, setValues] = useState(initialFieldValues);
        const [filtered, setFiltered] = useState(null);
      
        let history = useHistory();
        const dispatch = useDispatch();
        // getting of tutorlist
        let tutor = useSelector((state) => state.tutor.list);
        // sorting of tutors on date
        let tutorList = tutor.sort((a, b) => b.updatedOn.localeCompare(a.updatedOn));
      
        useEffect(() => {
          dispatch(actions.fetchAll());
        }, []);
      
        console.log("tutorList:", tutorList);
      
        // Variable to hold the filtered list before putting into state
      
        let newList = [];
        let filtered = tutorList;
        //when filter changes from '' to something filtered should be updated with newlist
      
        function handleChange(e) {
          const { name, value } = e.target;
          const fieldValue = { [name]: value };
          setValues({
            ...values,
            ...fieldValue,
          });
      
          // If the search bar isn't empty
          if (values.search !== "") {
            // Use .filter() to determine which items should be displayed
            // based on the search terms
            newList = tutorList.filter((item) => {
              // change current item to lowercase
              const lc = item.fullName.toLowerCase();
              // change search term to lowercase
              const filter = e.target.value.toLowerCase();
              console.log("filter", filter);
              // check to see if the current list item includes the search term
              // If it does, it will be added to newList. Using lowercase eliminates
              // issues with capitalization in search terms and search content
              return lc.includes(filter);
            });
          } else {
            newList = tutorList;
          }
          console.log("newList:", newList); //shows correct list
          setFiltered(newList); // update filtered state
          console.log("filtered:", filtered); //shows correct value
        }
      
        return (
          <div>
            <br />
            <TextField
              name="search"
              variant="outlined"
              label="Search Tutor"
              paceholder="search tutor..."
              value={values.search}
              onChange={handleChange}
            />
      
            {filtered && <TutorList tutorList={filtered} />}
      
            <Button
              onClick={() => history.goBack()}
              size="small"
              variant="contained"
              color="secondary"
            >
              back
            </Button>
          </div>
        );
      };
      
      export default Tutors;
      

      【讨论】:

      • 感谢您的帮助。我已经尝试过了,因为我在utorList上使用了分页,由于null的未定义长度它不起作用。如果我在const [filtered, setFiltered] = useState(null);中使用数组[]而不是null,它不会第一次呈现。它显示空列表。跨度>
      • 只使用条件渲染。 {filtered &amp;&amp; &lt;TutorList tutorList={filtered} /&gt;}
      猜你喜欢
      • 2021-01-12
      • 2020-08-01
      • 2021-03-14
      • 2022-01-07
      • 1970-01-01
      • 2019-12-15
      • 1970-01-01
      • 2019-07-28
      • 1970-01-01
      相关资源
      最近更新 更多