Error: Cannot read properties of undefined (reading 'props') in ReactJS

Error: Cannot read properties of undefined (reading 'props') in ReactJS

我似乎无法获得用于将信息从我的 child class 传递到我的 parent class 的道具。我想做的是检测某人选择了哪个下拉菜单选项,将该信息发送到 parent class 然后接受所选选项并运行对后端的调用然后 returns 与所选选项匹配的数据库项目列表。

下面是child class:

import React,{useState} from 'react';
import SEPractices from "../dummydata/SEPractices"

  const optionItems = SEPractices.map((SEPractice) =>
                <option key={SEPractice.practice}>{SEPractice.practice}</option>
            );
  const Dropdown = () => {
  const [selectValue, setValue] = useState("")
    
  const handleSelect = (e) => {
    console.log(e.target.value);
    setValue(e.target.value);
    this.props.handlePractice(e.target.value);
}

    return (
        <div>
             <select value={selectValue} onChange={handleSelect}> 
                
               <option value="dummyData">
                 Select an SE Practice
                 </option>
                {optionItems}
             </select>
         </div>

    )
  }
  export default Dropdown;

下面是parent class:

import React,{useState} from "react";
import Styles from "../components/tablestyle.js";
import Table from "../components/evidencetable.js";
import tablecolumns from "../components/tablecolumns.js";
import Dropdown from "../components/Dropdown.js";
import axios from "axios";

//const dbArticles = [];
class SEPractice extends React.Component{
  /*constructor(props){
  this.state = {dbArticles: []};
  this.componentDidMount = this.componentDidMount.bind(this);
  this.getArticles = this.getArticles.bind(this);
  this.practice = this.practice.bind(this);
  }*/
  state={
    dbArticles: []
  }
  
  handlePractice (Option) {
  
    console.log("hi");

    // axios.get(`https://protected-plains-77403.herokuapp.com/api/articles/${Option}`)
    axios.get(`https://localhost:5000/api/articles/${Option}`)
    .then((response) =>{
      const data = response.data;
      this.setState({dbArticles: data});
      console.log('state', this.state);
    })
    .catch(()=>{
      alert('error retrieving data');
    });
  }

  componentDidMount = () =>{
    this.getArticles();
  }
  getArticles = () =>{
    axios.get('https://protected-plains-77403.herokuapp.com/api/articles')
    .then((response) =>{
      const data = response.data;
      this.setState({dbArticles: data});
      console.log('state', this.state);
    })
    .catch(()=>{
      alert('error retrieving data');
    });
  }
/*practice =() =>{
  const [selected, setSelected] = useState('');
  const practiceHandler = (e) =>{
    setSelected(e);
  }
}*/
render() {
    return (

      <div>
        <h2>Select SE Practice to get evidence for the claimed benefits</h2>
            <Dropdown onDropdown={this.handlePractice}/>
            <Styles>
                <Table
                data={this.state.dbArticles}
                columns={tablecolumns}
                />
            </Styles>
      </div>
    );
}
}
export default SEPractice;  

我关注了几篇文章和堆栈溢出博客,他们都说要做 this.props.method 我做了:

  const handleSelect = (e) => {
    console.log(e.target.value);
    setValue(e.target.value);
    this.props.handlePractice(e.target.value);
}

您没有在组件中收到任何道具,因为您不允许使用该参数并且还对不正确的道具名称进行操作:

const Dropdown = () => { // missing props here
  const [selectValue, setValue] = useState("")
    
  const handleSelect = (e) => {
    console.log(e.target.value);
    setValue(e.target.value);
    this.props.handlePractice(e.target.value); // problem here
}

    return (
        <div>
             <select value={selectValue} onChange={handleSelect}> 
                
               <option value="dummyData">
                 Select an SE Practice
                 </option>
                {optionItems}
             </select>
         </div>

    )
  }
  export default Dropdown;

领取道具更新:

const Dropdown = (props) => {
  const [selectValue, setValue] = useState("")
    
  const handleSelect = (e) => {
    console.log(e.target.value);
    setValue(e.target.value);
    props.onDropdown(e.target.value); // note correct name
}

    return (
        <div>
             <select value={selectValue} onChange={handleSelect}> 
                
               <option value="dummyData">
                 Select an SE Practice
                 </option>
                {optionItems}
             </select>
         </div>

    )
  }
  export default Dropdown;

Codesandbox Demo

您需要将代码更改为


const handleSelect = (e) => {
    console.log(e.target.value);
    setValue(e.target.value);
    this.props.onDropdown(e.target.value);
}


原因是因为在下拉组件上您将道具命名为 onDropdown

当你在 setState 之后尝试 console.log 你的状态时,请这样做

      const data = response.data;
      this.setState({dbArticles: data},() => console.log('state', this.state));
    }) 

原因是 setState 是异步的,第二个参数是在实际设置状态后触发的回调。

在父 class 中,您没有正确绑定构造函数中的方法。您需要以下内容:

class SEPractice extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
       dbArticles: []
    }

    this.handlePractice = this.handlePractice.bind(this);
  }

handlePractice 方法现在绑定到父组件。当您将它传递给子组件时,您将它分配给 属性 onDropdown。然后,您需要使用分配给它的 onDropdown 属性 从子组件正确访问它。请注意,因为子组件是 functional 组件,所以我们不使用 this.props,就像您在 [=24= 的父组件中所做的那样] 组件。像这样:

  const Dropdown = (props) => { //Notice here we passed props into the function that generates the component
    const [selectValue, setValue] = useState("")
    
    const handleSelect = (e) => {
      console.log(e.target.value);
      setValue(e.target.value);
      props.onDropdown(e.target.value); //Not this.props
    }

    return (
        <div>
             <select value={selectValue} onChange={handleSelect}> 
                
               <option value="dummyData">
                 Select an SE Practice
                 </option>
                {optionItems}
             </select>
         </div>

    )
  }
  export default Dropdown;

}