react中不依賴redux等這些進行狀态管理的話,主要是有父元件給子元件傳值,子元件給父元件傳值,還有兄弟元件之前的傳值
這是一個評論功能的小栗子,非常适合來說明元件之前傳值的問題
首先上個項目檔案目錄結構
這裡一共有四個元件Comment是最外層的容器元件,CommentInput是負責輸入,
其餘兩個負責評論展示
子元件給父元件傳值
先了解一下定義:react中state改變了,元件才會update。父寫好state和處理該state的函數,同時将函數名通過props屬性值的形式傳入子,子調用父的函數,同時引起state變化。子元件要寫在父元件之前
子元件與父元件之前存在繼承的關系,是以子元件可以調用父元件的方法。
class CommentInput extends React.Component {
constructor(props) {
super(props)
this.state = {
username: "",
content: ""
}
}
show = () => {
if (this.props.onSubmit) {
const { username, content } = this.state
this.props.onSubmit({username, content})
}
this.setState({ content: "" })
}
handleContent = (e) => {
this.setState(
{ content: e.target.value }
)
}
handleUserName = (e) => {
this.setState(
{ username: e.target.value }
)
}
render() {
return (
<div className="comment-input">
<div className="input-filed">
<span className="input-filed-name">使用者名:</span>
<div className="input-filed-content">
<input type="text" value={this.state.username} onChange={this.handleUserName} />
</div>
</div>
<div className="input-filed">
<span className="input-filed-name">評論内容:</span>
<div className="input-filed-content">
<textarea value={this.state.content} onChange={this.handleContent} />
</div>
</div>
<div className="input-filed-btn">
<button onClick={this.show}>釋出</button>
</div>
</div>
);
}
}
注意類中的show()方法
show = () => {
if (this.props.onSubmit) {
const { username, content } = this.state
this.props.onSubmit({username, content})
}
this.setState({ content: "" })
}
同樣我們給出父元件CommentApp的代碼
class CommentApp extends Component {
constructor(props) {
super(props)
this.state = {
comments: []
}
}
handleSubmit = (comment) => {
if (!comment) return
if (!comment.username) return alert('請輸入使用者名')
if (!comment.content) return alert('請輸入評論内容')
this.state.comments.push(comment)
this.setState(
{
comments: this.state.comments
}
)
}
render() {
return (
<div className="wrapper">
<CommentInput onSubmit={this.handleSubmit} />
<CommentList comments={this.state.comments} />
</div>
);
}
}
同樣請注意父元件中的onSubmit={this.handleSubmit} 方法,是不是發現了子元件中有this.props.onSubmit這麼個語句,這個原理就是子元件給父元件props傳值時通過父元件定義的方法去改變父元件的state
父元件給子元件傳值
相較于子元件給父元件傳值來說,父元件給子元件傳值就簡單的多了,我們都知道class有構造函數constructor,通常我們是這麼寫的。以父元件CommentApp為例
constructor(props) {
super(props)
this.state = {
comments: []
}
}
其中的props就是從父元件中繼承的,裡面可以有屬性、方法。那父元件是怎麼給子元素傳入的呢?繼續往下看:還是父元件CommentApp為例
render() {
return (
<div className="wrapper">
<CommentInput onSubmit={this.handleSubmit} />
<CommentList comments={this.state.comments} />
</div>
);
}
代碼中,父元件給CommentList傳了一個叫comments={this.state.comments} comment的屬性,再看子元件CommentList中
class CommentList extends React.Component {
static defaultProps = {
comments: []
}
render() {
return (
<div>
{this.props.comments}
{this.props.comments.map((comment, i) => {
return (
<Comment comment={comment} key={i} />
)
})}
</div>
)
}
}
CommentList元件中使用this.props.comments 就能把comments取出,是不是簡單許多。
兄弟元件傳值
隻聽說過父子元件之間的傳值,卻是不知道兄弟元件怎麼傳值,是不是需要用到第三方的狀态管理呢?事實上,元件的狀态多了對于我們來說并不是什麼好事,因為狀态多容易産生混亂,雖然說第三方的狀态管理能我們省下不少事,但是也不能盲目的使用。如果元件之間不是多層嵌套,傳值可以直接react解決
這個例子中CommentsList和CommentsInput就是一個兄弟元件,公共附件即為CommentApp。是以CommentApp就是兩個子元件“溝通”的橋梁
回頭看,CommentInput 需要把輸入的内容在CommentIist中顯示處理啊,就需要每次都把内容傳給CommentIist。但是CommentInput 先把值傳給了父元素CommentApp
CommentInput中片段
show = () => {
if (this.props.onSubmit) {
const { username, content } = this.state
this.props.onSubmit({username, content})
}
this.setState({ content: "" })
}
content就是我們擷取的内容。
CommentApp代碼片段
render() {
return (
<div className="wrapper">
<CommentInput onSubmit={this.handleSubmit} />
<CommentList comments={this.state.comments} />
</div>
);
}
這就是兄弟元件之間的傳值方式。
本文的例子來自于《React.js 小書》,學習過程中覺得這個例子可以很好的說明元件之間的傳值關系,如需源碼,可以留言哈,待我“收拾”下GitHub倉庫項目後放在留言區
這是第一次寫技術部落格,如有錯誤歡迎指正,有什麼問題也可以給我留言哦!