redux 的原理

index.js

import React from 'react'
import ReactDOM from 'react-dom'
import App from './App'

ReactDOM.render(
  (
      <App/>
  ),
  document.querySelector('#root')
)

App.js

import React, { Component } from 'react'
import Add from './components/Add'
import List from './components/List'

/*
1.引入Provider包裹需要共享數據的結構,並且設置data,這是data就是共享數據
2.需要使用共享數據的組件,就引入withData高階組件做修飾。
*/

import {Provider} from './HOC/withData'


const data = {
  list: [],
  title: 'app',
  name: 'zhangsan',
  userid: '1293'
};


export default class App extends Component {
  
  render() {
    return (
        
      <Provider data={data}>

          <div className="app">
            <Add/>
            <List/>
          </div>
      
      </Provider>
    )
  }
}

HOC/withData.js 高階組件

import React, {Component} from 'react'

const DataContext = React.createContext({
  globalData: {}
});


export class Provider extends Component{
  constructor(props) {
    super(props);
    //props.data   state.globalData
    this.state = {
      globalData: {...props.data}
    }

    this.methods = {
      change: (newData)=>{
        this.setState({
          globalData: {
            ...this.state.globalData,
            ...newData
          }
        });
      }
    }
  }
  
  render(){
    return (
      <DataContext.Provider value={{globalData: this.state.globalData, ...this.methods }}>
        {this.props.children}
      </DataContext.Provider>
    );
  }


  
}


export const withData = (Com, handleData = {})=>{
  class withData extends Component{
    constructor(props) {
      super(props);
      let newHandleData = {};
      Object.keys(handleData).forEach(key=>{
        let newFunc = handleData[key].bind(this, this.dispatch);
        newHandleData[key] = newFunc;
      });
      
      this.state = {
        newHandleData
      }

    }
    
    render(){
      return <Com {...this.context.globalData} {...this.state.newHandleData} {...this.props}/>
    }

    dispatch=(cb)=>{
      let result = cb(this.context.globalData);
      this.context.change(result);
    }
    
  }
  withData.contextType = DataContext;
  return withData;
}


Add.js 需要使用 withData 修飾的組件

import React, { Component } from 'react'
import {withData} from '../HOC/withData'


let id = 1;
class Add extends Component {

  render() {
    return (
      <div>
        <h1>新增</h1>
        <input type="text" ref={el=>(this.input=el)}/>
        <button onClick={this.addAction.bind(this)}>新增</button>
      </div>
    )
  }

  addAction(){
    this.props.add({
      value: this.input.value,
      id: id++,
      status: 'todo'
    });
    this.input.value = '';
  }

}


const handleData = {
  add(dispatch, params){

    dispatch((globalData)=>{
      return {
        list: [...globalData.list, params]
      }
    });
    
  }
  
}




export default withData(Add, handleData);
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章