React,Redux,React-redux的錯綜複雜關係

耀九天發表於2018-08-18

最近了解了一些React的知識,在這裡寫一些關於React.js,Redux和React-redux的知識,供大家學習

一.React
1.首先要知道React不是mvc框架,它只是一個庫,只專注於檢視,也就是v 而我們用到Rreact是React.js進行web app的開發
react的技術棧:react.js + react-router + redux +es6 + webpack + fetch

先來一個小例子認識一下元件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <script src="./js/react.js"></script>
    <script src="./js/react-dom.js"></script>
    <script src="./js/browser-5.8.38.min.js"></script>
    <title>Document</title>
</head>
<body>
    <h1>例項</h1>
    <div id="example"></div>
</body>
<script type="text/babel">
    //定義元件
    var Example = React.createClass({
        render(){
            return(
                <div>
                    <h1>This is an Example</h1>
                </div>
           )
        }
    })
    ReactDOM.render(<Example/>,document.getElementById("example"));
</script>
</html>
複製程式碼

結果如下

React,Redux,React-redux的錯綜複雜關係
需要注意的是:
1.要設定type的屬性為text/babel
2.元件類的名稱必須是首字母大寫
3.有且只能有一個根節點,並且所有的標籤都必須關閉

2.React以元件的方式去構成UI,將UI上的功能定義成元件,然後將小的元件通過組合或者巢狀的方式構成大的元件,完成UI的構建。

(1)先了解一下state(狀態) React中使用state:
定義初始狀態,使用getInitialState
獲取狀態,使用this.state.狀態名
設定狀態,使用this.setState方法

例如:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <script src="./js/react.js"></script>
    <script src="./js/react-dom.js"></script>
    <script src="./js/browser-5.8.38.min.js"></script>
    <title>Document</title>
</head>
<body>
    <h1>例項</h1>
    <div id="example"></div>
</body>
<script type="text/babel">
    //定義元件
    var Example = React.createClass({
        //定義初始狀態
        getInitialState(){
            return{
                name:"dog",
                age:10
            }
        },
        onClick(){
            this.setState({
                age:this.state.age+1
            })
        },
        render(){
            return(
                <div>
                    <h1>This is an Example</h1>
                     {/*獲取狀態*/}
                    <h3>{this.state.name}</h3>
                    <h3>{this.state.age}</h3>
                    <button onClick={this.onClick}>++age</button>
                </div>
           )
        }
    })
    ReactDOM.render(<Example/>,document.getElementById("example"));
</script>
</html>
複製程式碼

結果如下:

React,Redux,React-redux的錯綜複雜關係

(2)props
在react中,屬性(props)就是用來實現父子元件通訊的。父元件向子元件傳遞的,可以傳遞資料和方法,在react中傳遞是單向的,只能父元件向子元件傳遞
在父元件中設定屬性,在子元件中獲取屬性。
在子元件中是通過this.props.屬性名來獲取傳遞的屬性

如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <script src="./js/react.js"></script>
    <script src="./js/react-dom.js"></script>
    <script src="./js/browser-5.8.38.min.js"></script>
    <title>Document</title>
</head>
<body>
    <h1>例項</h1>
    <div id="example"></div>
</body>
<script type="text/babel">
    //定義父元件
var Father = React.createClass({
    render(){
        return(
            <div>
                <h1>father</h1>
                <Son name="小強"></Son>
            </div>
        )
    }
})
//定義子元件
var Son = React.createClass({
    render(){
        return(
            <div>
                <h1>son</h1>
                <h3>{this.props.name}</h3>
            </div>
        )
    }
})
ReactDOM.render(<Father/>,document.getElementById("example"))
</script>
</html>
複製程式碼

結果如下:

React,Redux,React-redux的錯綜複雜關係

3.因此由上面的例子可知

state是讓元件控制自己的狀態,props是讓外部對元件自己進行配置 ,如果不知道用什麼,那麼就使用props。

一般react自己可以單獨完成一個專案

二.Redux
redux是JavaScript狀態容器,提供可預測化的狀態管理

可以讓你構建一致化的應用,執行於不同的環境(客戶端、伺服器、原生應用),並且易於測試。

Redux 試圖讓 state 的變化變得可預測,同時可以集中管理
有三大原則 :

1.單一資料來源

object tree中只存在唯一一個store中

2.state是隻讀的

唯一改變 state 的方法就是觸發 action,action 是一個用於描述已發生事件的普通物件

3.使用純函式來執行修改

為了描述 action 如何改變 state tree ,你需要編寫 reducers。Reducer只是一些純函式,它接收先前的 state 和 action,並返回新的 state。

使用純函式來執行修改,為了描述 action 如何改變 state tree ,你需要編寫 reducers

下面就是完成一個redux的大致過程

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <script src="./js/redux.js"></script>
</head>
<body>
    <h2>Redux物件</h2>
    <script>
        {/*console.log(Redux);
        定義初始的狀態*/}
        const initState = {
            count:99
        }
        {/*定義增加的action
        之前定義的action
        const increment = {
            type:"INCREMENT",
            step:3
        }
        現在定義的action*/}
        function increment(step){
            return{
                type:"INCREMENT",
                step
            }
        }
        {/*之前定義減少的action
        const decrement = {
            type:"DECREMENT"
        }
        現在定義減少的action*/}
        function decrement (step) {
            return{
                type:"DECREMENT",
                step
            }
        }
        {/*定義一個reducer 根據action中不同的type屬性,完成對state的更新操作*/}
        function reducer(state=initState,action){
            switch(action.type){
                case "INCREMENT":
                    return {count:state.count+action.step}
                case "DECREMENT":
                    return {count:state.count-action.step}
                default:
                    return state;
            }
        }
        {/*建立store物件*/}
        const store = Redux.createStore(reducer)
        console.log(store.getState())
        {/*訂閱功能就是得到的*/}
        store.subscribe(()=>{
            console.log("現在的狀態為:", store.getState())
        })
        {/*通過dispatch action完成狀態的修改*/}
        store.dispatch(increment(1))
        store.dispatch(increment(2))
        store.dispatch(increment(3))
    </script>
</body>
</html>
複製程式碼

結果如下:

React,Redux,React-redux的錯綜複雜關係
!!!另外注意你的action是同步的還是非同步的

在沒有非同步的action時 是這樣建立store的

//建立store
const store = createStore(reducer,state)
複製程式碼

非同步時需要對store進行增強

在createStore方法上使用,中介軟體applyMIddleware是對store進行增強的

const createStoreWithMiddleware = applyMiddleware(
    thunkMiddleware
)(createStore);
//建立store
const store = createStoreWithMiddleware(reducer,state)
複製程式碼

Redux是一個提供可預測化的狀態管理,它自己是無法實現專案的。

三.React-Redux:
1.從字面上看就知道了,react-redux就是將react和redux連線起來

我們已經定義好了react的元件和redux的狀態管理器,這時需要連線react和redux,將專案合併,必不可少的要用到react-redux的connect方法將笨拙的元件生成容器元件

呼叫connect方法的格式如下:

connect (mapStateToProps,mapDispatchToProps)(展示元件)

mapStateToProps是從state物件到props物件的對映,以state為引數

mapDispatchToProps是從笨拙元件方法到store.dispatch方法的對映,以dispatch為引數, 可以使用bindActionCreators(actionCreators,dispatch)來定義

//定義mapStateToProps
function mapStateToProps(state){
   return{
       counter:state.counter
   }
}
//定義mapDispatchToProps
function mapDispatchToProps(dispath){
   return bindActionCreators(actions,dispath)
}

//將Counter變數成容器元件並匯出
export default connect (mapStateToProps,mapDispatchToProps)(Counter)
// 如此一來,我們的counter就變成了一個容器元件,
// 狀態和方法都作為元件的props來使用的。
複製程式碼

2.Provider元件的作用,就是給後代元件提供store物件。
通常需要放到入口的js檔案中

<Provider store={store}>
        <App />
    </Provider>,
複製程式碼

通過Provider可以使後代使用store物件

使用props將屬性和方法傳遞到子元件中,讓子元件呼叫方法實現

class Counter extends Component{
    render(){
        console.log(this.props)
        return(
            <div>
                <Show counter={this.props.counter}/>
                <p>
                    <Add increment={this.props.increment}   />&nbsp;
                    <Sub decrement={this.props.decrement}  />&nbsp;
                    <AsyncAdd incrementAsync={this.props.incrementAsync} />&nbsp;
                    <OddAdd incrementIfOdd={this.props.incrementIfOdd} />
                </p>
            </div>
        )
    }
}
複製程式碼

四.從上面的知識可以知道:

react就是一個狀態機,用於構建使用者介面的。react本身是有狀態管理機制的。定義初始狀態,根據狀態渲染介面,修改狀態是通過setState來實現的。也就是單獨使用react可以完成一個不大的專案。

redux是狀態管理器,只是用來管理狀態的,它是一個獨立的狀態管理工具,可以在任何地方使用 ,要完成大的專案就必須要使用redux了。

但是隻有react和redux是不行的,因為react和redux是單獨存在的一個庫,必須要有一個庫來使它們連線起來,而這個庫就是react-reudx。

因此react,redux和react-redux在完成大型專案時是必不可少的。

相關文章