【问题标题】:Updating state of parent component when a child component is clicked, returns an error saying "cannot read property..."单击子组件时更新父组件的状态,返回错误“无法读取属性...”
【发布时间】:2020-04-26 14:59:34
【问题描述】:

我正在尝试在单击子组件时更新父组件状态。我似乎能够从子组件传递我需要的信息,并且当我 console.log 它工作的站名时。当我尝试更新状态时,问题就开始了。它返回一个错误,指出“无法读取未定义的属性 'setState'”。我不确定它为什么这样做?

子组件


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



【问题讨论】:

    标签: javascript reactjs


    【解决方案1】:

    将您的事件处理程序转换为箭头函数,否则 this 未定义:

    handleSearch(e) {
       // this is undefined 
       this.setState(); // => "Cannot read property 'setState' of undefined"
    }
    
    handleSearch = (e) => {
       // this is defined
       this.setState(); // works :)
    }
    

    【讨论】:

    • 谢谢!这行得通。我确实认为这是问题所在,但没有正确实现代码。
    【解决方案2】:

    对于构造函数中的函数,您必须 bind this:

    this.clickHandler = this.clickHandler.bind(this)
    //other functions
    

    或者,更改声明类型:

    clickHandler = (e) => {//your code}
    //other functions
    

    将此解决方案应用于handleSearch,clickHandler,searchFocusHandler 函数

    【讨论】:

      猜你喜欢
      • 2018-04-08
      • 2021-10-30
      • 1970-01-01
      • 2021-03-02
      • 2019-06-26
      • 1970-01-01
      • 2018-10-09
      • 1970-01-01
      • 2017-09-28
      相关资源
      最近更新 更多