简体   繁体   中英

React.js: Set a Default value into a prop

Fellows I have made this Component that creates a simple Button:

class AppButton extends Component {

  setOnClick() {
    if(!this.props.onClick && typeof this.props.onClick == 'function') {
      this.props.onClick=function(){ alert("Hello"); }
    }
  }

  setMessage() {
    if(!this.props.message){
        this.props.message="Hello"
    }
  }

  render(){
    this.setOnClick()
    this.setMessage()
    return (
      <button onClick={this.props.onClick}>{this.props.message}</button>
    )
  }
}

And I have an another Component that renders 2 Buttons:

class App extends Component {
  render() {
    return (
          <AppButton onClick={function(){ alert('Test Alert') } } message="My Button" />
          <AppButton />
    );
  }
}

But I get the following error:

TypeError: can't define property "message": Object is not extensible

On the line that says:

        this.props.message="Hello"

in method setMessage of the AppButton class.

Edit 1

I generated the react application using npm and me package.json has the following content

{
  "name": "sample",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "react": "^15.5.4",
    "react-dom": "^15.5.4"
  },
  "devDependencies": {
    "react-scripts": "1.0.7"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test --env=jsdom",
    "eject": "react-scripts eject"
  }
}

I believe that defaultProps should do what you need:

import PropTypes from 'prop-types';

class AppButton extends Component {
 render(){
    return (
      <button onClick={this.props.onClick}>{this.props.message}</button>
    )
  }
};

AppButton.propTypes = {
  message: PropTypes.string,
  onClick: PropTypes.func
};

AppButton.defaultProps = {
  message: 'Hello',
  onClick: function(){ alert("Hello"); }
};

From the docs:

The defaultProps will be used to ensure that this.props.name will have a value if it was not specified by the parent component. The propTypes typechecking happens after defaultProps are resolved, so typechecking will also apply to the defaultProps.

Edit for clarity : There should be no need for you setMessage in this instance.

return (
      <button onClick={this.props.onClick}>{this.props.message || "Default text"}</button>
);

This will check the value of prop and if it is undefined or null, the default message will replace the prop.

Are you using React v.14 or above? the props object is now frozen and cant be changed. You can use React.cloneElement instead

You cant set props, you must use state instead.

If you need to change the value, then it should be stored in the state due to props are static.

You should do it in this way:

this.setState({message: 'your message'});

And in the render method use it as:

{this.state.message}

As a recomendation, you should also initialize the state with that value in the constructor:

constructor(props){
  super(props);

  this.state = {
    message: ''
  }
}

The same will happend to setOnClick

You will find here a good explanation about this.

for deafault props you can do this

 const { 
     message = '', 
     onClick = (e)=>{} 
 } = props;

and use these variables without props keyword (you can still use props for not defined props values)

<button onClick={onClick}>{message}</button> 
{props.value}

But for your error it is just fine to handel error like:

{props.message ?? ''}

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