编程知识 cdmana.com

Simple use of status data management (context, mobx, Redux)

Context

establish Context object

// context.ts
const MyContext = React.createContext(defaultValue);
 Copy code 

Provide Context object

import MyContext from './context';

class APP extends React.Component {
  construct(props) {
    super(props);

    // value  When the value is the object , Status raised to  state, Prevent parent component refresh from causing unnecessary rendering of child components 
    this.state = {
      theme: themes.light,
      toggleTheme: this.toggleTheme,
    };
    
    this.toggleTheme = this.toggleTheme.bind(this);
  }
  
  //  How to change the theme color 
  toggleTheme () {
    this.setState(state => ({
      theme: state.theme === themes.dark
      ? themes.light
      : themes.dark,
    }));
  }

  render() {
    return (
      <MyContext.Provider value={this.state}> {this.props.children} </MyContext.Provider>
    )
	}
}
 Copy code 

subscribe Context object

//  Method 1:
class MyClass extends React.Component {
  componentDidMount() {
    let value = this.context;
    /*  After the component is mounted , Use  MyContext  Component to perform side-effect operations  */
  }

  render() {
    let value = this.context;
    /*  be based on  MyContext  Component values for rendering  */
  }
}

MyClass.contextType = MyContext;


//  Method 2: public class fields  grammar 【 Experimental grammar 】
class MyClass extends React.Component {
  static contextType = MyContext;
 
  render() {
    let value = this.context;
    /*  Rendering based on this value  */
  }
}
 Copy code 

consumption Context object

import { MyContext } from './context';

function ThemeTogglerButton() {
  // Theme Toggler  Buttons don't just get  theme  value , It also comes from  context  Get a  toggleTheme  function 
  return (
    <MyContext.Consumer> {(context) => { const {theme, toggleTheme} = context; return ( <button onClick={toggleTheme} style={{backgroundColor: theme.background}} > Toggle Theme </button> ) }} </MyContext.Consumer>
  );
}

export default ThemeTogglerButton;
 Copy code 

More detailed use :

React Context Basic understanding

React Hooks

Mobx

establish observable object

explain :

  • @observable Indicates that the data can be monitored , It's global data
  • @action Represents the method of modifying global shared data

RootStore

// mobx/index.ts
import { observable, action } from "mobx";

class RootStore {
  //  Phone number 
  @observable mobile = '';
  // token
  @observable token = '';

  //  Set data information 
  @action setUserInfo(mobile, token) {
    this.mobile = mobile;
    this.token = token;
  }

  //  Clear data information 
  @action clearUserInfo() {
    this.mobile = '';
    this.token = '';
  }
}

export default new RootStore();
 Copy code 

UserStore

// mobx/userStore.ts
import { observable, action } from "mobx";

class UserStore {
  //  User information object 
  @observable user = {};

  //  Set user information 
  @action setUser(user) {
    this.user = user;
  };

  //  Clear user information 
  @action clearUser() {
    this.user = {};
  }
}

export default new UserStore();
 Copy code 

Provide observable object

import React from 'react';
import { Provider} from 'mobx-react';
import RootStore from './mobx';
import UserStore from './mobx/userStore'

const APP = (props) => {
  return (
  	<Provider RootStore={RootStore} UserStore={UserStore}> {props.children} </Provider>
  )
}
 Copy code 

Inject 、 subscribe observable object

  • @inject("RootStore") Inject observable object , Get global data RootStore

  • @observer monitor observable Object data changes , Re render the global data of the update component

Class component

import React from 'react';
import { inject, observer } from 'mobx-react';

@inject('RootStore') //  Inject  RootStore
@inject('UserStore') //  Inject  UserStore
@observer
class Demo extends React.Component {
  componentDidMount() {
    //  obtain  mobx  Internal  RootStore  object 
    console.log(this.props.RootStore);
  }
  
  render() {
    return null
  }
}
 Copy code 

Function component

import React from 'react';
import { inject, observer } from 'mobx-react';

const Demo = (props) => {
  React.useEffect(() => {
    //  obtain  mobx  Internal  RootStore  object 
    console.log(props.RootStore);
  }, []);
  
  return null
}

//  Inject  RootStore
export default inject('RootStore')(observer(Demo));

//  Inject  RootStore、 UserStore
export default inject('RootStore')(inject('UserStore')(observer(Demo)));
 Copy code 

Redux

Redux Is a use called action Events to manage and update application status patterns and tool Libraries

establish reducer Pure function

** Return value :** Latest status value state

//  initial  state  value 
const initialState = [];

// reducer  Pure function 
const reducer = (state = initialState, action) => {
    switch(action.type) {
        //  Reset  state
        case 'reset':
            return { ...action.state };
        //  to update  state
        case 'update':
            return Object.assign({}, state, action.payload);
        default:
            return state;
    }
}

export default reducer;
 Copy code 

** explain :** By distributing action Of type Type to perform the corresponding data update operation

Integrate multiple reducer

Will be multiple reducer Pure functions are integrated and can be renamed

import { combineReducers } from 'redux';
import test1Reducer from './test1Reducer';
import test2Reducer from './test2Reducer';

const reducer = combineReducers({
  test1: test1Reducer,
  test2: test2Reducer
});
 Copy code 

create data source store

// store.ts
import reducer from './reducer';

const store = createStore(reducer);
 Copy code 

Provide Store

import React from 'react'
import ReactDOM from 'react-dom'
import { Provider } from 'react-redux'

import App from './App'
import store from './store'

ReactDOM.render(
  <Provider store={store}> <App /> </Provider>,
  document.getElementById('root')
)
 Copy code 

connect

connect([mapStateToProps], [mapDispatchToProps], [mergeProps], [options])
 Copy code 

mapStateToProps

mapStateToProps It's a function , mapping store From the data in to the component props in

mapStateToProps(state, ownProps):stateProps
 Copy code 

Parameters :

  • state Redux Medium store
  • ownProps Of the component itself props attribute

** Return value :** Return to one object object , The return value object is associated with props Merge

explain :

  • mapStateToProps Will subscribe to... Based on parameters store or ownProps The state of change ( If you write this parameter, you will subscribe , If you don't write, you won't subscribe )

Example

class Demo extends Component {
  static PropTypes = {
    userId: PropTypes.string.isRequired,
    user: PropTypes.object
  };
   
  render(){
    return <div> user name :{this.props.user.name}</div>
  }
}

const mapStateToProps = (state, ownProps) => {
  // state  yes  { userList: [{id: 0, name: ' The king 2 '}] }
  return {
    //  lookup  store  in  userList  The data source  id  by  userId  User data passed to  props 
    user: _.find(state.userList, {id: ownProps.userId})
  }
}
 
const MyComp = connect(mapStateToProps)(Demo);
 Copy code 

mapDispatchToProps

mapDispatchToProps Used to create a component ``store.dispatch The mapping relation of , It could be a object`, You can also pass in functions

mapDispatchToProps(dispatch, ownProps): dispatchProps
 Copy code 

Parameters :

  • dispatch distribution action function
  • ownProps Of the component itself props attribute

mapDispatchToProps In three ways

  1. When connect(mapState, null) Do not pass the second parameter ( Or for null) when
this.props.dispatch({
  type:ChangeColor,
  payload:{
    color: e.target.value
  }
})
 Copy code 
  1. When connect(mapState,mapDispatch) The second parameter of is function when
// mapDispatch  For a function 
const mapDispatchToProps = (dispatch) => ({
  changeColor : (value) => (dispatch({
    type:ChangeColor,
    payload:{
      color: value
    }
  })),
})
 Copy code 
  1. When connect(mapState,mapDispatch) The second parameter of is object when
// mapDispatch  For an object 
const changeColor = (v) => ({
  type: ChangeColor,
  payload:{
    color:v
  }
})

const mapDispatchToProps = {
  changeColor ,
}
 Copy code 

Redux It also provides bindActionCreators function , to action Wrapped as a directly callable function .

import {bindActionCreators} from 'redux';

const changeColor = {
  type: ChangeColor,
  payload:{
    color: value
  }
}
 
const mapDispatchToProps = (dispatch, ownProps) => {
  return bindActionCreators({
    changeColor,
  });
}
 Copy code 

react-thunk

Creating store Create in file thunk middleware

install

npm install react-thunk
 Copy code 

establish Store file

import { createStore, applyMiddleware ,compose } from 'redux’; import thunk from 'redux-thunk’; 
import reducer from './reducers’; const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ ? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({}) : compose; const enhancer = composeEnhancers(applyMiddleware(thunk)) let store = createStore(reducer, window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()); let store = createStore(reducer, enhancer); export default store;  Copy code 

establish Action Type file

export const  UPDATE_List = 'update_list';
 Copy code 

establish Action file

// actions.ts
//  Update data information 
const changeArticles = (data) => {
    return {
        type: UPDATE_List,
        data,
    }
}

// redux-thunk actionCreator【 Created  action  Function can return a function ( You can call  axios  Perform asynchronous request data operations )】
export const getDataAxAction = (params) => {   
  return (dispatch, getState) => {     
    axios.get(url, { params })
      .then((res)=>{       
        // res.data.data.list【 Get the query results and distribute them again action, establish action And assign the asynchronous request result to action.value On 】 
        dispatch(changeArticles(res.data.data.list));
      }).catch((error)=>{       
        console.log(error);     
    	})
  }; 
}
 Copy code 

Use in components

import React from 'react';
import { getDataAxAction } from './actions';

class Demo extends React.Component {
	
  //  change  params  To get the latest  list  Data and information 
  updateList() {
    const params = { page: 0, pageSize: 10 };
    this.props.updateList(params);
  }
  
  render(){
    const { list } = this.props;
    return (
    	<div onClick={updateList}> to update  list  data </div>
    )
  }
}

//  mapping  state to props
const mapStateToProps = (state, ownProps) => {
  return {
    list: state.data
  }
}

//  mapping  dispatch to props
const mapDispatchToProps = (dispatch) => ({
  updateList : (params) =>(
    dispatch(getDataAxAction(params))
  ),
})

const MyComp = connect(mapStateToProps, mapDispatchToProps)(Demo);
 Copy code 

react-saga

Creating store Create in file saga middleware

install

npm install react-saga
 Copy code 

establish store file

import { createStore, applyMiddleware, compose } from 'redux’; import reducer from './reducers’; 
import createSagaMiddleware  from 'redux-saga’; import mySagas from './mySagas’;

const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ ? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({}) : compose;
const sagaMiddleware = createSagaMiddleware(); 
const enhancer = composeEnhancers(applyMiddleware(sagaMiddleware)) 

let store = createStore(reducer, enhancer); 

// Use it here  mySagas【 stay store Create good after , Use the middleware after it is hung mySagas】 
sagaMiddleware.run(mySagas);

export default store;
 Copy code 

establish Action Type file

export const  UPDATE_PARAMS = 'update_params';

export const  UPDATE_List = 'update_list';
 Copy code 

establish Action file

// actions.ts
//  to update  params  Data and information 
const updateParams = (params) => {
  return {
    type: UPDATE_PARAMS,
    params,
  }
}

//  Update data information 
const changeArticles = (data) => {
    return {
        type: UPDATE_List,
        data,
    }
}
 Copy code 

establish mySagas file

import { takeEvery, put } from ‘redux-saga/effects’;

// establish  mySagas【generator function 】 After the function , Creating  store  Used in the warehouse  mySagas【saga  The intermediate plug-in calls  run  Methods use 】
function* mySagas(){  
    // Listen to someone  action,  Then execute the second parameter  gengerator  function  
    yield takeEvery(UPDATE_PARAMS, getList);   
}

// Parameters  action  That's the corresponding  action  object  
function* getList(action){   
    // Send asynchronously , Distribute after asynchrony succeeds  action 
    let res = yield axios.get(url, { params: action.params });   
    //put  It's forwarding  action, Be similar to  dispatch, Then execute the synchronization request and execute the corresponding business logic processing  
    yield put(changeArticles(res.data.list)); 
}
 Copy code 

Use in components

import React from 'react';
import { updateParams } from './actions';

class Demo extends React.Component {
	
  //  change  params  To get the latest  list  Data and information 
  changeParams() {
    const params = { page: 0, pageSize: 10 };
    this.props.changeParams(params);
  }
  
  render(){
    const { list } = this.props;
    return (
    	<div onClick={changeParams}> to update  list  data </div>
    )
  }
}

//  mapping  state to props
const mapStateToProps = (state, ownProps) => {
  return {
    list: state.data
  }
}

//  mapping  dispatch to props
const mapDispatchToProps = (dispatch) => ({
  changeParams : (params) =>(
    dispatch(updateParams(params))
  ),
})

const MyComp = connect(mapStateToProps, mapDispatchToProps)(Demo);
 Copy code 

react-thunk And react-saga The difference between

react-thunk

// redux-thunk actionCreator【 Created  action  Function can return a function ( You can call  axios  Perform asynchronous request data operations )】
export const getDataAxAction = (params) => {   
  return (dispatch, getState) => {     
    axios.get(url, { params })
      .then((res) => {       
        // res.data.data.list【 Get the query results and distribute them again action, establish action And assign the asynchronous request result to action.value On 】 
        dispatch(changeArticles(res.data.data.list));
      }).catch((error) => {       
        console.log(error);     
    	})
  }; 
}
 Copy code 

explain :

When we return a function ,store Will help us call the returned function , And the dispatch Exposed for our use . about redux-thunk For the whole process , It is to wait until the asynchronous task is completed , Let's call dispatch, Then go to store To call reducer.

react-saga

import { takeEvery,put } from ‘redux-saga/effects’;

// establish  mySagas【generator function 】 After the function , Creating  store  Used in the warehouse  mySagas【saga  The intermediate plug-in calls  run  Methods use 】
function* mySagas(){  
    // Listen to someone  action,  Then execute the second parameter  gengerator  function  
    yield takeEvery(UPDATE_PARAMS, getList);   
}

// Parameters  action  That's the corresponding  action  object  
function* getList(action){   
    // Send asynchronously , Distribute after asynchrony succeeds  action 
    let res = yield axios.get(url, { params: action.params });   
    //put  It's forwarding  action, Be similar to  dispatch, Then execute the synchronization request and execute the corresponding business logic processing  
    yield put(changeArticles(res.data.list)); 
}
 Copy code 

explain :

When we dispatch Of action Type not in reducer In the middle of the day ,redux-saga Monitor function of takeEvery It will monitor , When the asynchronous task has a result, execute put Method , amount to dispatch, Trigger... Again dispatch. about redux-saga For the whole process , It's waiting for the execution action and reducer after , Judge reducer Do you have this in it action.

版权声明
本文为[Fragrant orange]所创,转载请带上原文链接,感谢
https://cdmana.com/2021/09/20210909131415408e.html

Scroll to Top