【问题标题】:Error: Cannot read properties of undefined (reading 'props') in ReactJS错误:无法在 ReactJS 中读取未定义的属性(读取“道具”)
【发布时间】:2021-11-18 03:47:36
【问题描述】:

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

下面是子类:

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;

下面是父类:

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);
}

【问题讨论】:

    标签: javascript reactjs react-props


    【解决方案1】:

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

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

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

      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;
    
    }
    

    【讨论】:

    • 感谢您的回答,非常感谢!当我进行更改时,我仍然在子类中收到 'props' is not defined no-undef 错误。
    • 这个错误什么时候出现?当您尝试从下拉列表中进行选择时?
    • 运行时出错。因此,一旦我启动 Node.js 服务器,它就会说编译失败,然后是错误。
    • 哦,我的错,我错过了(道具)!它现在正在工作!非常感谢。
    【解决方案2】:

    您需要将代码更改为

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

    原因是因为在下拉组件中您将 prop 命名为 onDropdown

    当您在执行setState 之后尝试控制台记录您的状态时,请这样做

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

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

    【讨论】:

    • 感谢您对代码的改进!这很有道理。当我将其更改为 onDropdown 时,我仍然会收到 'props' is not defined no-undef 错误。
    【解决方案3】:

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

    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

    【讨论】:

    • 我进行了更改,但似乎仍然收到 'props' is not defined no-undef 错误。也感谢您的评论!
    • 查看演示,最好保留类或功能组件,不要混合使用两者。
    猜你喜欢
    • 2018-04-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-15
    • 2022-01-01
    • 2021-12-31
    • 2018-03-24
    • 1970-01-01
    相关资源
    最近更新 更多