React.js: Set a Default value into a prop
JavascriptReactjsEcmascript 6Javascript Problem Overview
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"
}
}
Javascript Solutions
Solution 1 - Javascript
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.
Solution 2 - Javascript
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.
Solution 3 - Javascript
Are you using React v.14 or above? the props object is now frozen and cant be changed. You can use React.cloneElement instead
Solution 4 - Javascript
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.
Solution 5 - Javascript
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 ?? ''}