【问题标题】:Reactjs/Graphql: TypeError: Object(...) is not a functionReactjs/Graphql: TypeError: Object(...) is not a function
【发布时间】:2019-01-10 19:18:36
【问题描述】:

选择日期和时间然后单击提交按钮后,我收到以下错误:

TypeError: Object(...) 不是函数

对象指的是Action,它是一个查询,所以我不明白为什么它说它不是一个函数。另外,请查看 handleSubmit 事件并确保我正确调用 Action。谢谢!!

渲染组件

class Calendar extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      inputValue: ""
    };

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

  handleSubmit = event => {
    event.preventDefault();

    console.log(this.state.inputValue);
    this.setState({
      inputValue: new Date(document.getElementById("time").value).valueOf()
    });
    Action({
      variables: {
        timestamp: this.state.inputValue
      }
    });

    console.log(this.state.inputValue);
  };

  render() {
    console.log(this.props);
    return (
      <div className="Calendar">
        <form onSubmit={this.handleSubmit.bind(this)}>
          <label>Date/Time</label>
          <input type="datetime-local" id="time" step="1" />
          <input type="submit" value="Submit" />
        </form>
      </div>
      //{this.render(){return (<UserList />)};
    );
  }
}

export default graphql(Action, {
  options: props => ({
    variables: {
      timestamp: props.inputValue
    }
  })
})(Calendar);

动作查询

const Action = gql`
  query($timestamp: Float!) {
    action(timestamp: $timestamp) {
      action
      timestamp
      object {
        filename
      }
    }
  }
`;

【问题讨论】:

    标签: javascript reactjs graphql


    【解决方案1】:

    这不是重新获取查询的正确方法。

    代替

    Action({
      variables: {
        timestamp: this.state.inputValue
      }
    });
    

    试试

    handleSubmit = event => {
        event.preventDefault();
    
        console.log(this.state.inputValue);
        this.setState({
          inputValue: new Date(document.getElementById("time").value).valueOf()
        }, () => {
          this.props.data.refetch({
            timestamp: +this.state.inputValue
          });
          console.log(this.state.inputValue);
        });
      };
    

    如果你不想调用这个道具data,你可以在你的 HOC 上重命名它graphql,像这样:

    export default graphql(Action, {
      name: 'WHATEVERNAME'
      options: props => ({
        variables: {
          timestamp: props.inputValue
        }
      })
    })(Calendar);
    

    那么您将调用 this.props.WHATEVERNAME 而不是 this.props.data

    希望对你有帮助:D

    顺便说一句,您绑定了您的 handleSubmit 方法 3 次。您只需执行一次:

    1. 不建议在渲染中绑定,因为您将在每次重新渲染时处理绑定:

    因此您可能希望将&lt;form onSubmit={this.handleSubmit.bind(this)}&gt; 更改为&lt;form onSubmit={this.handleSubmit}&gt;

    1. 您可以像以前那样将它绑定到构造函数上。那没问题。但这有点冗长。我会删除它。

    3.handleSubmit = event =&gt; { 通过像您一样将方法声明为箭头函数,该方法会自动绑定到this。所以我会保留它并删除其他 2 :)

    PS:请注意,如果您要编写 handleSubmit(e) {},则在第 3 号上它不会绑定到 this,因此您需要其他两种方法之一。但同样,数字 3 是最有效的绑定方式 :) 只需删除其他 2 就可以了。

    【讨论】:

    • 现在我得到了这个:[GraphQL error]: Message: Variable "$timestamp" of required type "Float!" was not provided., Location: [object Object], Path: undefined 告诉我时间戳值没有传递给查询?
    • 您可能希望将 refetch 查询作为 setState 的回调来调用 ... 由于它是异步的,您可能正在使用以前的状态调用 refetch 查询,而不是您想要的新状态。
    • 查看建议的答案...刚刚编辑了 :) 除此之外,你能把你的新代码放在我可以看看的地方吗?
    • 请注意,refetch 查询现在在作为第二个参数发送到 setState 函数的函数回调中,这样我可以保证当我调用 this.state 时我将获得更新的值
    • 这正是 refetch 正在做的事情...检查您在 chrome 开发工具上的网络选项卡...您必须在提交时使用时间戳提出了新请求
    猜你喜欢
    • 2019-01-30
    • 1970-01-01
    • 1970-01-01
    • 2018-11-16
    • 2019-04-05
    • 2020-08-03
    • 1970-01-01
    • 2018-12-24
    • 2021-10-26
    相关资源
    最近更新 更多