簡體   English   中英

反應:TypeError:this.props.update 不是函數

[英]React: TypeError: this.props.update is not a function

首先讓我說我對整個編程非常陌生,所以如果我問愚蠢的問題,請不要問我。

基本上,我正在嘗試將日期選擇器添加到反應中的搜索應用程序,我在那里有 UI,並且我可以在代碼中預先設置日期范圍。 但是我希望用戶能夠為搜索結果選擇開始和結束日期。

我知道我的代碼不完整,我知道我哪里出錯了,但我只是不知道如何“修復”它。

日期選擇器:

import React from "react";
import "date-fns";

import { Paper } from "@material-ui/core";

import DateFnsUtils from "@date-io/date-fns";
import {
  MuiPickersUtilsProvider,
  KeyboardDatePicker,
} from "@material-ui/pickers";

class DatePickerWidget extends React.Component {
  render() {
    return (
      <Paper id="date-picker-widget" elevation={8}>
        <Paper id="date-filters" elevation={8}>
          <MuiPickersUtilsProvider utils={DateFnsUtils}>
            <KeyboardDatePicker
              margin="normal"
              id="date-picker-dialog"
              label="Start Date"
              format="yyyy/MM/dd"
              value={this.props.startDate}
              maxDate={this.props.endDate}
              onChange={(date) => this.props.update({ startDate: date })}
              KeyboardButtonProps={{
                "aria-label": "change start date",
              }}
            />
            <KeyboardDatePicker
              margin="normal"
              id="date-picker-dialog"
              label="End Date"
              format="yyyy/MM/dd"
              value={this.props.endDate}
              minDate={this.props.startDate}
              onChange={(date) => this.props.update({ endDate: date })}
              KeyboardButtonProps={{
                "aria-label": "change end date",
              }}
            />
          </MuiPickersUtilsProvider>
        </Paper>
      </Paper>
    );
  }
}

export default DatePickerWidget;

顯示日期選擇器的搜索框:

    import React from "react";

import { TextField, Button, Typography } from "@material-ui/core";

import "./SearchBox.css"
import DatePickerWidget from "./DatePickerWidget"

class SearchBox extends React.Component {
  constructor(props) {
    super(props);
    this.state = { searchTerm: "", results: "" };

    this.handleSubmit = this.handleSubmit.bind(this);
    this.handleChange = this.handleChange.bind(this);
    this.validateSearch = this.validateSearch.bind(this);
    this.clear = this.clear.bind(this);

  
  }

  componentDidMount() {
    this.setState({ searchTerm: this.props.searchTerm });
  }
  componentDidUpdate(prevProps) {
    if (prevProps.searchTerm !== this.props.searchTerm)
      this.setState({ searchTerm: this.props.searchTerm });
  }

  handleChange(event) {
    this.setState({ [event.target.name]: event.target.value });
  }

  handleSubmit(event) {
    event.preventDefault();
    this.props.update({ searchTerm: this.state.searchTerm });
    this.setState({ results: this.state.searchTerm });
  }

  validateSearch() {
    return this.state.searchTerm !== "";
  }

  clear() {
    this.setState({ searchTerm: "", results: "" });
    this.props.update({ searchTerm: "" });
  }

  render() {
    return (
      <React.Fragment>
        <form id="search-form" onSubmit={this.handleSubmit}>
          <Button
            style={{ width: "40%" }}
            variant="outlined"
            color="primary"
            onClick={this.clear}
            disabled={this.state.results === ""}
          >
            Clear
          </Button>
          <TextField
            style={{ flexBasis: "100%" }}
            variant="outlined"
            label="Search Term"
            type="search"
            name="searchTerm"
            value={this.state.searchTerm}
            onChange={this.handleChange}
          />
          <Button
            style={{ width: "40%" }}
            variant="contained"
            color="primary"
            disabled={!this.validateSearch()}
            type="submit"
          >
            Search
          </Button>


          <DatePickerWidget startDate="2020/09/01" endDate="2020/09/30"/>
        </form>

        
        {this.state.results && (
          <Typography align="center" variant="body1">
            Displaying results for: {this.state.results}
          </Typography>
        )}
      </React.Fragment>
    );
  }
}


export default SearchBox;

更改界面上的日期時出現的錯誤:

類型錯誤:this.props.update 不是函數

          format="yyyy/MM/dd"
          value={this.props.startDate}
          maxDate={this.props.endDate}
        > onChange={(date) => this.props.update({ startDate: date })}
          KeyboardButtonProps={{
            "aria-label": "change start date",

我相當確定代碼沒問題,我只是沒有向搜索框添加一些內容,使用戶能夠更新日期范圍。

我還應該提到,我知道這不會對搜索結果返回的內容產生任何影響。 讓該功能發揮作用是我的下一個挑戰。

提前致謝!

*編輯:我忘了提到我沒有編寫所有這些代碼。 我的任務是學習如何將這個小功能添加到整個編程的介紹中。

**編輯:有人可以告訴我一個修復嗎? 就像我說的,我對此很陌生,我還沒有完全理解一切。

它們接受任意輸入(稱為“道具”)並返回描述應該出現在屏幕上的內容的 React 元素。 - 看這里

“props” 是將用戶輸入傳輸到組件中的通道。 例如

<DatePickerWidget startDate="2020/09/01" endDate="2020/09/30"/>

在您的 DatePickerWidget 組件中,您可以通過this.props.startDate讀取用戶的輸入“2020/09/01”。 如果您想從 DatePickerWidget this.props.update作為函數讀取,那么您需要在使用它時輸入一個函數。 就像

<DatePickerWidget startDate="2020/09/01" endDate="2020/09/30"/ update=<your_update_handler>>

我猜你想將 SearchBox 的update函數傳遞給 DatePickerWidget,所以你可以這樣做

<DatePickerWidget startDate="2020/09/01" endDate="2020/09/30"/ update=this.props.update>

props 對象上沒有稱為 update 的函數。 您可以在要使用 this.props.update 的組件的父組件中定義一個名為 update 的函數。 然后將其傳遞給子組件,如下所示:


<SearchBox update={this.props.update}/>

但是您可能正在尋找的是更新 SearchBox 的狀態。 state 可以在組件內部更改,而 props 不能直接更改,只能通過在父組件中進行更改。

在搜索欄中

import React from "react";

import { TextField, Button, Typography } from "@material-ui/core";

import "./SearchBox.css"
import DatePickerWidget from "./DatePickerWidget"

class SearchBox extends React.Component {
  constructor(props) {
    super(props);
    this.state = { searchTerm: "", results: "" };

    this.handleSubmit = this.handleSubmit.bind(this);
    this.handleChange = this.handleChange.bind(this);
    this.validateSearch = this.validateSearch.bind(this);
    this.clear = this.clear.bind(this);

  
  }

  componentDidMount() {
    this.setState({ searchTerm: this.props.searchTerm });
  }
  componentDidUpdate(prevProps) {
    if (prevProps.searchTerm !== this.props.searchTerm)
      this.setState({ searchTerm: this.props.searchTerm });
  }

  handleChange(event) {
    this.setState({ [event.target.name]: event.target.value });
  }

  handleSubmit(event) {
    event.preventDefault();
    this.props.update({ searchTerm: this.state.searchTerm });
    this.setState({ results: this.state.searchTerm });
  }

  validateSearch() {
    return this.state.searchTerm !== "";
  }

  clear() {
    this.setState({ searchTerm: "", results: "" });
    this.props.update({ searchTerm: "" });
  }

  render() {
    return (
      <React.Fragment>
        <form id="search-form" onSubmit={this.handleSubmit}>
          <Button
            style={{ width: "40%" }}
            variant="outlined"
            color="primary"
            onClick={this.clear}
            disabled={this.state.results === ""}
          >
            Clear
          </Button>
          <TextField
            style={{ flexBasis: "100%" }}
            variant="outlined"
            label="Search Term"
            type="search"
            name="searchTerm"
            value={this.state.searchTerm}
            onChange={this.handleChange}
          />
          <Button
            style={{ width: "40%" }}
            variant="contained"
            color="primary"
            disabled={!this.validateSearch()}
            type="submit"
          >
            Search
          </Button>


          <DatePickerWidget startDate="2020/09/01" endDate="2020/09/30" update={() => console.log('props passed')}/>
        </form>

        
        {this.state.results && (
          <Typography align="center" variant="body1">
            Displaying results for: {this.state.results}
          </Typography>
        )}
      </React.Fragment>
    );
  }
}


export default SearchBox;

在你的日期選擇器中

import DateFnsUtils from "@date-io/date-fns";
import {
  MuiPickersUtilsProvider,
  KeyboardDatePicker,
} from "@material-ui/pickers";

class DatePickerWidget extends React.Component {
  render() {
    return (
      <Paper id="date-picker-widget" elevation={8}>
        <Paper id="date-filters" elevation={8}>
          <MuiPickersUtilsProvider utils={DateFnsUtils}>
            <KeyboardDatePicker
              margin="normal"
              id="date-picker-dialog"
              label="Start Date"
              format="yyyy/MM/dd"
              value={this.props.startDate}
              maxDate={this.props.endDate}
              onChange={(date) => this.props.update({ startDate: date })}
              KeyboardButtonProps={{
                "aria-label": "change start date",
              }}
            />
            <KeyboardDatePicker
              margin="normal"
              id="date-picker-dialog"
              label="End Date"
              format="yyyy/MM/dd"
              value={this.props.endDate}
              minDate={this.props.startDate}
              onChange={ this.props.update}
              KeyboardButtonProps={{
                "aria-label": "change end date",
              }}
            />
          </MuiPickersUtilsProvider>
        </Paper>
      </Paper>
    );
  }
}

export default DatePickerWidget;

這一切都是因為您從未將任何道具從父級傳遞給您的 DatePicker

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM