關於react的幾個網站:
小書:http://huziketang.mangojuice.top/books/react/
組件傳值的方法:
一、父子組件間的傳值(主要是利用 props 來進行交流,父組件用this.state傳值,子組件用this.prop):
如果組件嵌套層次太深,那么從外到內組件的交流成本就變得很高,通過 props 傳遞值的優勢就不那么明顯了。
Father.jsx文件
import
React, {
Component}
from
'react'
import
Son
from
'./Son.jsx'
{/*引入子組件*/}
export
default
class
Father
extends
Component{
constructor(){
super();
this.
state = {
message:
'hello',
sonVal:
null
}
}
render(){
return (
<
div
id=
"father"
>
<
h1
>Father組件
</
h1
>
<
button
onClick=
{()
=>{
this.
setState({
message:
'world'})}
}
>
修改
</
button
>
{
/* <Son data="test data value"/> */
}
<
p
>選擇了那種水果:
{this.
state.
sonVal
}
</
p
>
<
Son
data=
{this.
state.
message
}
handle=
{this.
testAction.
bind(
this)
}
/>
{/*子組件中傳遞參數或者方法*/}
</
div
>
)
}
// 接收子組件數據
testAction(
value){
console.
log(
this);
console.
log(
value);
this.
setState({
sonVal:
value});
} }
Son.jsx
import
React, {
Component}
from
'react'
export
default
class
Son
extends
Component{
constructor(){
super();
this.
state = {
select:
'蘋果'
}
}
render(){
let
arr = [
'蘋果',
'香蕉',
'西瓜'];
return (
<
div
id=
"son"
>
<
h1
>Son組件
</
h1
>
<
p
>接收到的值為:
{this.
props.
data
}
</
p
>
{
arr.
map((
item,
index)
=>{
return (
<
p
key=
{
index
}
>
{
item
}:
<
input
type=
"radio"
value=
{
item
}
checked=
{this.
state.
select ==
item
}
onChange=
{this.
inputChange.
bind(
this)
}
/>
</
p
>
)
})
}
</
div
>
)
}
inputChange(
ev){
let
value =
ev.
target.
value;
this.
setState({
select:
value});
// 調用父組件的方法,將值傳遞給父組件
this.
props.
handle(
value);
}
}
二.(父組件)向更深層的(子組件) 進行傳遞信息 >>利用(context)
通過添加 childContextTypes 和 getChildContext() 到 第一層組件MessageList ( context 的提供者),React 自動向下傳遞數據然后在組件中的任意組件(也就是說任意子組件,在此示例代碼中也就是 Button )都能通過定義 contextTypes(必須指定context的數據類型) 訪問 context 中的數據。這樣就不需要通過第二層組件進行傳遞了。
指定數據並要將數據傳遞下去的父組件要定義 childContextTypes 和 getChildContext() ;想要接收到數據的子組件 必須定義 contextTypes 來使用傳遞過來的 context 。
var
Button =
React.
createClass({
// 必須指定context的數據類型
contextTypes: {
color:
React.
PropTypes.
string
},
render
:
function() {
return (
<
button
style=
{{
background:
this.
context.
color}
}
>
{this.
props.
children
}
</
button
>
);
}
});
var
Message =
React.
createClass({
render
:
function() {
return (
<
div
>
{this.
props.
text
}
<
Button
>Delete
</
Button
>
</
div
>
);
}
});
var
MessageList =
React.
createClass({
//父組件要定義 childContextTypes 和 getChildContext()
childContextTypes: {
color:
React.
PropTypes.
string
},
getChildContext
:
function() {
return {
color:
"purple"};
},
render
:
function() {
var
children =
this.
props.
messages.
map(
function(
message) {
return
<
Message
text=
{
message.
text
}
/>;
});
return
<
div
>
{
children
}
</
div
>;
}
});
三、子組件向父組件傳值
【子組件】控制自己的 state 然后告訴【父組件】的點擊狀態,然后在【父組件】中展示出來
// 父組件
var
MyContainer =
React.
createClass({
getInitialState
:
function () {
return {
checked:
false
};
},
onChildChanged
:
function (
newState) {
this.
setState({
checked:
newState
});
},
render
:
function() {
var
isChecked =
this.
state.
checked ?
'yes' :
'no';
return (
<
div
>
<
div
>Are you checked:
{
isChecked
}
</
div
>
<
ToggleButton
text=
"Toggle me"
initialChecked=
{this.
state.
checked
}
callbackParent=
{this.
onChildChanged
}
/>
</
div
>
);
}
});
// 子組件
var
ToggleButton =
React.
createClass({
getInitialState
:
function () {
return {
checked:
this.
props.
initialChecked
};
},
onTextChange
:
function () {
var
newState = !
this.
state.
checked;
this.
setState({
checked:
newState
});
// 這里要注意:setState 是一個異步方法,所以需要操作緩存的當前值
this.
props.
callbackParent(
newState);
},
render
:
function () {
// 從【父組件】獲取的值
var
text =
this.
props.
text;
// 組件自身的狀態數據
var
checked =
this.
state.
checked;
return (
<
label
>
{
text
}:
<
input
type=
"checkbox"
checked=
{
checked
}
onChange=
{this.
onTextChange
}
/></
label
>
);
}
});
四、沒有任何嵌套關系的組件之間傳值(比如:兄弟組件之間傳值)
推薦一個相關博客:https://blog.csdn.net/u011439689/article/details/51955991
ProductSelection和Product本身是沒有嵌套關系的,而是兄弟層級的關系。但通過在ProductSelection組件中訂閱一個消息,在Product組件中又發布了這個消息,使得兩個組件又產生了聯系,進行傳遞的信息。所以根據我個人的理解,當兩個組件沒有嵌套關系的時候,也要通過全局的一些事件等,讓他們聯系到一起,進而達到傳遞信息的目的。
One.jsx文件
import
React, {
Component}
from
'react'
import
PubSub
from
'pubsub-js'
export
default
class
One
extends
Component{
constructor(){
super();
console.
log(
'constructor');
this.
state = {
message:
null
}
}
render(){
console.
log(
'render');
return (
<
div
>
<
h1
>One組件
</
h1
>
<
p
>接收到的值為:
{this.
state.
message
}
</
p
>
</
div
>
)
}
// 創建並且渲染完成的方法
componentDidMount(){
console.
log(
'componentDidMount');
//監聽子組件的事件
this.
token =
PubSub.
subscribe(
'send-data', (
eventName,
data)
=>{
console.
log(
'subscribe執行了');
console.
log(
data);
this.
setState({
message:
data});
})
// $on
}
//組件將要銷毀
componentWillUnmount(){
console.
log(
'componentWillUnmount');
// 組件銷毀時,需要移除監聽
PubSub.
unsubscribe(
this.
token);
// $off
}
}
Two.jxs
import
React, {
Component}
from
'react'
import
PubSub
from
'pubsub-js'
export
default
class
Two
extends
Component{
render(){
return (
<
div
>
<
h1
>Two組件
</
h1
>
<
input
type=
"text"
ref=
"in"
/>
<
button
onClick=
{this.
sendAction.
bind(
this)
}
>發送
</
button
>
</
div
>
)
}
sendAction(){
// 發送信息給one組件
PubSub.
publish(
'send-data',
this.
refs.
in.
value);
// $emit
}
}
五.利用react-redux進行組件之間的狀態信息共享
如果是比較大型的項目,可以使用react-redux,這方面的資料可以參考阮一峰的網絡日志。
http://github.com/mroderick/PubSubJS