2017-06-07 33 views
5

研究員我有此組件創建一個簡單的按鈕: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('Fuck You') } } message="Fucked up Button" /> 
      <AppButton /> 
    ); 
    } 
} 

但我得到以下錯誤:

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

在這行:

 this.props.message="Hello" 

AppButton類的方法setMessage

編輯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

旁註 - 我絕對喜歡你的警報和信息。這實際上表明,您一直在努力按照自己的意願實現這一目標。我知道那些感覺很好。 – Ohgodwhy

+0

我只是爲了好玩。根本沒有汗水! –

+0

是甚至有效?兩個根節點? –

回答

15

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

從文檔:

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.

編輯爲清楚起見:應該有在這種情況下沒有必要爲你setMessage

+0

有時我用ES6解構''{names = []}'指定默認值'' –

+1

@Pedrammarandi yep,如果你正在創建一個功能組件而不需要生命週期鉤子,這也是一個好方法。 –

0

您使用的陣營第14節或以上?道具的對象現在被凍結,不能改變。你可以使用React.cloneElement代替

0

你不能設置道具,你必須使用狀態來代替。

如果您需要更改該值,則應該將其存儲在由於道具狀態爲靜態的狀態。

你應該這樣做了這種方式:

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

而在渲染方法使用它作爲:

{this.state.message} 

作爲recomendation,你也應與該值初始化狀態構造函數:

constructor(props){ 
    super(props); 

    this.state = { 
    message: '' 
    } 
} 

同樣將happend到setOnClick

你會發現here對此有一個很好的解釋。

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

這將檢查prop的值,如果未定義或爲null,則默認消息將替換prop。