Javascript 单击子组件时,更新父组件的状态会返回一个错误,显示“0”;无法读取属性…”;
我试图在单击子组件时更新父组件状态。我似乎能够从子组件传递所需的信息,并且当我在console.log中记录站点名称时,它就工作了。当我尝试更新状态时,问题开始出现。它返回一个错误,说明“无法读取未定义的属性'setState'。我不确定它为什么这样做 子组件Javascript 单击子组件时,更新父组件的状态会返回一个错误,显示“0”;无法读取属性…”;,javascript,reactjs,Javascript,Reactjs,我试图在单击子组件时更新父组件状态。我似乎能够从子组件传递所需的信息,并且当我在console.log中记录站点名称时,它就工作了。当我尝试更新状态时,问题开始出现。它返回一个错误,说明“无法读取未定义的属性'setState'。我不确定它为什么这样做 子组件 export default function StationListItem(props) { const boldString = (str, substr) => { var strRegExp = new Re
export default function StationListItem(props) {
const boldString = (str, substr) => {
var strRegExp = new RegExp(substr, "gi");
var newString = str.match(strRegExp);
var x = str.replace(newString, "<b>" + newString + "</b>");
return x;
};
const { name, query, action } = props;
return (
<li
onClick={() => {
action(name);
}}
name={name}
dangerouslySetInnerHTML={{ __html: boldString(name, query) }}
></li>
);
}
import "../../App.sass";
import StationListItem from "../Account/StationListItem";
const searchListStyles = {
margin: 0,
padding: 0,
listStyleType: "none",
border: "1px solid #ccc",
borderTop: "0px",
borderRadius: "0 0 5px 5px",
height: "100%",
maxHeight: "228px",
overflow: "scroll",
};
export default class SaveFavouriteStations extends Component {
constructor() {
super();
this.state = {
searchField_isFocused: false,
query: "",
stationsArr: [],
filteredArr: [],
selectedArr: ["Leigh-on-Sea"],
selected: "",
};
}
componentDidMount() {
fetch("api/stations")
.then((response) => {
return response.json();
})
.then((stations) => {
this.setState({ stationsArr: stations });
});
}
handleSearch(e) {
this.setState({ [e.target.name]: e.target.value.toLowerCase() });
const filtered = this.state.stationsArr.filter((station) => {
if (
station.station_name
.toLowerCase()
.includes(this.state.query.toLowerCase()) ||
station.crs_code.toLowerCase().includes(this.state.query.toLowerCase())
) {
return station;
}
});
this.setState({ filteredArr: filtered });
}
searchFocusHandler(e) {
console.log(e);
this.setState({ searchField_isFocused: true });
}
clickHandler(name) {
this.setState({
selected: name,
});
}
render() {
const {
filteredArr,
selectedArr,
query,
searchField_isFocused,
} = this.state;
const matchingStations = filteredArr.map((station) => {
return (
<StationListItem
key={station._id}
name={station.station_name}
query={query}
action={this.clickHandler}
/>
);
});
const selected = selectedArr.map((selected) => {
return selected;
});
return (
<div className="section favourite-stations">
<h1>Favourite Stations</h1>
<input
autoComplete="off"
className="text-input"
type="text"
name="query"
placeholder="Search for a station..."
onChange={(e) => {
this.handleSearch(e);
}}
onFocus={() => {
this.setState({ searchField_isFocused: true });
}}
onMouseDown={() => {
this.setState({ searchField_isFocused: false });
}}
/>
{searchField_isFocused ? (
<ul style={searchListStyles}>
{query.length >= 2 ? (
matchingStations
) : (
<div style={{ padding: "10px 0", color: "#ccc" }}>
Enter a station name or code
</div>
)}
</ul>
) : (
""
)}
<div>{selectedArr.length >= 1 ? selected : "no stations selected"}</div>
</div>
);
}
}
导出默认函数StationListItem(道具){
常量boldString=(str,substr)=>{
var stregexp=新的RegExp(substr,“gi”);
var newString=str.match(strRegExp);
var x=str.replace(newString,“+newString+”);
返回x;
};
const{name,query,action}=props;
返回(
{
行动(名称);
}}
name={name}
DangerouslySetinerHTML={{{uuuuHTML:boldString(名称,查询)}
>
);
}
父组件
export default function StationListItem(props) {
const boldString = (str, substr) => {
var strRegExp = new RegExp(substr, "gi");
var newString = str.match(strRegExp);
var x = str.replace(newString, "<b>" + newString + "</b>");
return x;
};
const { name, query, action } = props;
return (
<li
onClick={() => {
action(name);
}}
name={name}
dangerouslySetInnerHTML={{ __html: boldString(name, query) }}
></li>
);
}
import "../../App.sass";
import StationListItem from "../Account/StationListItem";
const searchListStyles = {
margin: 0,
padding: 0,
listStyleType: "none",
border: "1px solid #ccc",
borderTop: "0px",
borderRadius: "0 0 5px 5px",
height: "100%",
maxHeight: "228px",
overflow: "scroll",
};
export default class SaveFavouriteStations extends Component {
constructor() {
super();
this.state = {
searchField_isFocused: false,
query: "",
stationsArr: [],
filteredArr: [],
selectedArr: ["Leigh-on-Sea"],
selected: "",
};
}
componentDidMount() {
fetch("api/stations")
.then((response) => {
return response.json();
})
.then((stations) => {
this.setState({ stationsArr: stations });
});
}
handleSearch(e) {
this.setState({ [e.target.name]: e.target.value.toLowerCase() });
const filtered = this.state.stationsArr.filter((station) => {
if (
station.station_name
.toLowerCase()
.includes(this.state.query.toLowerCase()) ||
station.crs_code.toLowerCase().includes(this.state.query.toLowerCase())
) {
return station;
}
});
this.setState({ filteredArr: filtered });
}
searchFocusHandler(e) {
console.log(e);
this.setState({ searchField_isFocused: true });
}
clickHandler(name) {
this.setState({
selected: name,
});
}
render() {
const {
filteredArr,
selectedArr,
query,
searchField_isFocused,
} = this.state;
const matchingStations = filteredArr.map((station) => {
return (
<StationListItem
key={station._id}
name={station.station_name}
query={query}
action={this.clickHandler}
/>
);
});
const selected = selectedArr.map((selected) => {
return selected;
});
return (
<div className="section favourite-stations">
<h1>Favourite Stations</h1>
<input
autoComplete="off"
className="text-input"
type="text"
name="query"
placeholder="Search for a station..."
onChange={(e) => {
this.handleSearch(e);
}}
onFocus={() => {
this.setState({ searchField_isFocused: true });
}}
onMouseDown={() => {
this.setState({ searchField_isFocused: false });
}}
/>
{searchField_isFocused ? (
<ul style={searchListStyles}>
{query.length >= 2 ? (
matchingStations
) : (
<div style={{ padding: "10px 0", color: "#ccc" }}>
Enter a station name or code
</div>
)}
</ul>
) : (
""
)}
<div>{selectedArr.length >= 1 ? selected : "no stations selected"}</div>
</div>
);
}
}
导入“../../App.sass”;
从“./Account/StationListItem”导入StationListItem;
常量searchListStyles={
保证金:0,
填充:0,
listStyleType:“无”,
边框:“1px实心#ccc”,
边框顶部:“0px”,
边界半径:“0 0 5px 5px”,
高度:“100%”,
最大高度:“228px”,
溢出:“滚动”,
};
导出默认类saveFavoriteExtends组件{
构造函数(){
超级();
此.state={
searchField_聚焦:false,
查询:“”,
StationSharer:[],
筛选标准:[],
已选择的DARR:[“Leigh on Sea”],
选定:“,
};
}
componentDidMount(){
获取(“api/站点”)
。然后((响应)=>{
返回response.json();
})
。然后((站)=>{
this.setState({stationsArr:stations});
});
}
handleSearch(e){
this.setState({[e.target.name]:e.target.value.toLowerCase()});
const filtered=this.state.stationsArr.filter((站)=>{
如果(
station.station\u名称
.toLowerCase()
.includes(this.state.query.toLowerCase())||
station.crs_code.toLowerCase().includes(this.state.query.toLowerCase())
) {
返回站;
}
});
this.setState({filteredar:filteredar});
}
搜索聚焦处理器(e){
控制台日志(e);
this.setState({searchField_isFocused:true});
}
clickHandler(名称){
这是我的国家({
所选名称:,
});
}
render(){
常数{
过滤过滤器,
选择DARR,
查询
searchField_专注于,
}=本州;
const matchingStations=Filteredar.map((站)=>{
返回(
);
});
const selected=selectedArr.map((已选)=>{
返回选中的;
});
返回(
喜爱的电台
{
本研究(e);
}}
onFocus={()=>{
this.setState({searchField_isFocused:true});
}}
onMouseDown={()=>{
this.setState({searchField_isFocused:false});
}}
/>
{searchField\u是焦点(
{query.length>=2(
配对站
) : (
输入站点名称或代码
)}
) : (
""
)}
{selectedArr.length>=1?选中:“未选择任何电台”}
);
}
}
对于构造函数中的函数,您必须绑定此
:
this.clickHandler = this.clickHandler.bind(this)
//other functions
或者,更改声明类型:
clickHandler = (e) => {//your code}
//other functions
将此解决方案应用于
handleSearch、clickHandler、searchFocusHandler
函数您必须为构造函数中的函数绑定此:
this.clickHandler = this.clickHandler.bind(this)
//other functions
或者,更改声明类型:
clickHandler = (e) => {//your code}
//other functions
将此解决方案应用于handleSearch、clickHandler、searchFocusHandler
函数将事件处理程序转换为箭头函数,否则此
未定义:
handleSearch(e) {
// this is undefined
this.setState(); // => "Cannot read property 'setState' of undefined"
}
handleSearch = (e) => {
// this is defined
this.setState(); // works :)
}
将事件处理程序转换为箭头函数,否则此未定义:
handleSearch(e) {
// this is undefined
this.setState(); // => "Cannot read property 'setState' of undefined"
}
handleSearch = (e) => {
// this is defined
this.setState(); // works :)
}
谢谢这起作用了。我确实认为这是问题所在,但没有正确实现代码。谢谢!这起作用了。我确实认为这就是问题所在,但没有正确地实现代码。