【问题标题】:React: TypeError: this.props.update is not a function反应:TypeError:this.props.update 不是函数
【发布时间】:2021-01-04 01:43:05
【问题描述】:

首先让我说我对整个编程很陌生,所以如果我问愚蠢的问题,请坦率地告诉我。

基本上,我正在尝试将日期选择器添加到响应中的搜索应用程序,我在那里有 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;

我在界面上更改日期时遇到的错误:

TypeError: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",

我相当确定代码没问题,我只是没有在搜索框中添加一些内容,使用户能够更新日期范围。

我还应该提到,我知道这不会对搜索结果返回的内容产生任何影响。让该功能发挥作用是我的下一个挑战。

提前致谢!

*编辑:我忘了提到我没有编写所有这些代码。我的任务是学习如何添加这个小功能作为对整个编程的介绍。

**编辑:任何人都可以告诉我解决这个问题吗?就像我说的那样,我对此很陌生,我还没有完全理解所有内容。

【问题讨论】:

    标签: javascript reactjs material-ui jsx


    【解决方案1】:

    在搜索栏中

    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

    【讨论】:

    • 谢谢,但我不完全确定如何 这样做。对不起,这个世界很新鲜!
    • 编写更新函数并将其作为道具传递给 datePicker。你已经完成了。不要忘记喜欢这个答案,如果它在某种程度上有所帮助
    • 好的,再次感谢!更多的是我实际上不知道要写什么...我现在陷入了“教程地狱”,所以我盯着屏幕画了一个空白...跨度>
    【解决方案2】:

    它们接受任意输入(称为“props”)并返回描述应在屏幕上显示的内容的 React 元素。 - 见here

    “props”是将用户输入传输到组件中的通道。例如

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

    在您的 DatePickerWidget 组件中,您可以通过this.props.startDate 读取用户输入的“2020/09/01”。 如果您想将 this.props.update 作为 DatePickerWidget 中的函数读取,则需要在使用时输入函数。就像

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

    【讨论】:

    • 谢谢!因此,这阻止了我收到该错误,我可以输入日期,但是当我单击日期选择器选择日期时,它不会更新日期显示。但是我仍然没有收到错误,所以它比我正在做的更好!
    【解决方案3】:

    props 对象上没有名为 update 的函数。您可以在要使用 this.props.update 的组件的父组件中定义一个名为 update 的函数。然后将其传递给子组件,如下所示:

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

    但您可能正在寻找的是更新 SearchBox 的状态。 state 可以在组件内部更改,而 props 不能直接更改,只能通过更改父组件。

    【讨论】:

    • 谢谢!很抱歉提出这样的问题,但我在画一个空白......我将如何定义该功能?
    • 就像 javascript 类的任何函数一样。然后将其传递给子组件。每当子组件调用该函数时,它都会在父组件中被激活。 (例如,您可以更改父组件的状态,以便为所有子组件提供单一的事实来源。)
    猜你喜欢
    • 2017-01-28
    • 2019-08-03
    • 2022-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-13
    • 2020-10-12
    相关资源
    最近更新 更多