![](/img/trans.png)
[英]How would this React code look without React-hooks and with class components rather than functional components?(Button that open an additional window)
[英]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.