繁体   English   中英

根据 react-hooks 功能组件中的搜索结果更新子组件

[英]updating the Child Component based on search results in react-hooks functional components

我有使用react-hooks功能组件的 redux 的react-App ,它正确呈现子组件中的导师列表。 我在其中添加了一个搜索框并handlchange function 以更新列表组件(子组件)。 handlechange function 工作正常,并将新列表分配给newlist TutorList Component主体内部的filtered变量,但是在handlechange handlechange function主体之外filtered的值保持不变 Tutors.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组件应根据在搜索字段中输入的过滤器显示新列表。 任何一种帮助解决方法或更好的解决方案。在此先感谢。

创建一个新的 state

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

handleChange() function 内部将过滤后的元素设置为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;

无需更新从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

此外,无需将过滤后的值存储在 state 中。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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