简体   繁体   中英

why I am getting warning-Functions are not valid as a React child. …?

I was learning about various lifecycle components, so I have a counter in my code, which can be increased or decreased using buttons and I have a seed generator which should be called on button click and it should change the value of the counter to seed, I have added function for the seed to be set to Number.parseInt(Math.random() * 100)

when I run the code, it gives warning in chrome, 在此处输入图像描述

also when I click on increment, the counter is set to () => this.setState({ seed: Number.parseInt(Math.random() * 100) })1 , and when I press decrement(click) the counter is set to NaN. There was a similar question related to this warning but that code was not related to mine.

APP COMPONENT

import React from "react";
import Counter from "./Counter";
import "./App.css";
class App extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      mount: true,
      ignoreProp: 0,
      seed: 40
    };

    this.mountCounter = () => this.setState({ mount: true });
    this.unmountCounter = () => this.setState({ mount: false });

    this.ignoreProp = () => this.setState({ ignoreProp: Math.random() });
    this.seedGenerator = () =>
      this.setState({ seed: Number.parseInt(Math.random() * 100) });
  }

  render() {
    let counter = null;

    if (this.state.mount) {
      counter = (
        <Counter ignoreProp={this.state.ignoreProp} seed={this.seedGenerator} />
      );
    }

    return (
      <div className="App">
        <button onClick={this.mountCounter} disabled={this.state.mount}>
          Mount Counter
        </button>
        <button onClick={this.unmountCounter} disabled={!this.state.mount}>
          Unmount Counter
        </button>
        <button onClick={this.ignoreProp}>Ignore Prop</button>
        <button onClick={this.seedGenerator}>Generate seed</button>
        {counter}
      </div>
    );
  }
}

export default App;

COUNTER COMPONENT

import React from "react";

class Counter extends React.Component {
  constructor(props) {
    console.log("Constructor");
    super(props);
    this.state = {
      counter: 0,
      seed: 0
    };

    this.increment = () => this.setState({ counter: this.state.counter + 1 });
    this.decrement = () => this.setState({ counter: this.state.counter - 1 });
  }

  static getDerivedStateFromProps(props, state) {
    if (props.seed && state.seed !== props.seed) {
      return {
        seed: props.seed,
        counter: props.seed
      };
    }
    return null;
  }

  componentDidMount() {
    console.log("Component Did Mount");
    console.log("-------------------");
  }

  shouldComponentUpdate(nextProps, nextState) {
    if (
      nextProps.ignoreProp &&
      this.props.ignoreProp !== nextProps.ignoreProp
    ) {
      console.log("Should Component Update- DO NOT RENDER");
      return false;
    }
    console.log("Should Component Update- RENDER");
    return true;
  }

  render() {
    console.log("Render");

    return (
      <div>
        <button onClick={this.increment}>Increment</button>
        <button onClick={this.decrement}>Decrement</button>
        <div className="counter">Counter: {this.state.counter}</div>
      </div>
    );
  }

  componentDidUpdate(prevProps, prevState, snapshot) {
    console.log("Component Did Update");
    console.log("--------------------");
  }

  componentWillUnmount() {
    console.log("Component Will Unmount");
    console.log("----------------------");
  }
}

export default Counter;

You pass seedGenerator , a function, as the seed prop down to Counter , and since you have

return {
    seed: props.seed,
    counter: props.seed
}

in getDerivedStateFromProps (likely a copy-paste typo?), the

Counter: {this.state.counter}

render fragment tries to render seedGenerator , a function.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM