React.js: установить значение по умолчанию в опору

Ребята, я сделал этот компонент, который создает простую кнопку:

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

И у меня есть еще один компонент, который отображает 2 кнопки:

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

Но я получаю следующую ошибку:

TypeError: невозможно определить свойство "message": объект не является расширяемым

На линии, которая говорит:

        this.props.message="Hello"

в методе setMessage из AppButton класса.

Редактировать 1

Я сгенерировал приложение реагирования, используя npm и у меня package.json имеет следующий контент

{
  "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"
  }
}

Ответ 1

Я считаю, что defaultProps должен делать то, что вам нужно:

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"); }
};

Из документов:

Параметры DefaultProps будут использоваться, чтобы гарантировать, что this.props.name будет иметь значение, если он не был указан родительским компонентом. Проверка типов propTypes происходит после того, как defaultProps разрешены, поэтому typechecking также применим к файлам defaultProps.

Изменить для ясности. В этом случае вам не понадобится setMessage.

Ответ 2

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

Это проверит значение prop и, если оно undefined или null, сообщение по умолчанию заменит prop.

Ответ 3

Вы используете React v.14 или выше? объект реквизита теперь заморожен и не может быть изменен. Вместо этого вы можете использовать React.cloneElement

Ответ 4

Вы не можете настроить реквизиты, вы должны использовать это состояние.

Если вам нужно изменить значение, оно должно быть сохранено в состоянии из-за статических реквизитов.

Вы должны сделать это следующим образом:

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

И в методе рендеринга используйте его как:

{this.state.message}

В качестве рекомендации вы также должны инициализировать состояние с этим значением в конструкторе:

constructor(props){
  super(props);

  this.state = {
    message: ''
  }
}

То же самое произойдет с setOnClick

Вы найдете здесь хорошее объяснение.

Ответ 5

Вы увидите здесь хорошее объяснение по этому поводу.