React Redux

redux简述:
解决组件间状态共享的问题,原理是集中式管理,
主要有三个核心方法,action,store,reducer,
改变数据: 调用 store 的 dispatch 接收 action 传入 store,reducer 进行 state 操作,
获取数据:通过 store 提供的 getState获取数据

 

 

 

首先初始化创建一个项目,具体怎么创建不用说了吧

 
项目创建完后安装依赖:
npm install redux --save
npm install react-redux --save
npm install redux-thunk --save
 

在  src  目录下新建个  store  文件夹
store  文件夹下创建文件:actionTypes.js、reducer.js、actionCreators.js
目录结构长这样:
 
 actionTypes.js
通过action更改state的内容,每个数据更改动作描述为一个action
一个action是一个简单的对象,用来描述state发生了什么变更。说白了就是一个对象
export const ADD_ARTICLE = "ADD_ARTICLE"

 

reducer.js
reducer是个函数,它接收state、action为参数,返回新的state。
reducer只能处理同步的代码,后续会说怎样处理异步问题
一般在store文件夹内创建一个reducer.js文件

import * as actionTypes from "./actionTypes"

const initialState = {
  articles: [
    { id: 1, title: "标题1", body: "内容1" },
    { id: 2, title: "标题2", body: "内容2" },
  ],
}

const reducer = (state = initialState, action) => {
  switch (action.type) {
    case actionTypes.ADD_ARTICLE:
      const newArticle = {
        id: Math.random(), // 随机id
        title: action.article.title,
        body: action.article.body,
      }
      return {
        ...state,
        articles: state.articles.concat(newArticle),
      }
    default:;
  }
  return state
}
export default reducer

 

actionCreators.js
处理异步代码
import * as actionTypes from "./actionTypes"

export const addArticle = article => {
  return {
    type: actionTypes.ADD_ARTICLE,
    article,
  }
}

export const simulateHttpRequest = article => {
  return dispatch => {
    setTimeout(() => { // 模拟异步
      dispatch(addArticle(article))
    }, 3000)
  }
}

 

然后改造一下src下的index文件让redux与项目连接起来

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

// redux套件
import { createStore, applyMiddleware } from "redux"
import { Provider } from "react-redux"
import thunk from "redux-thunk"
import reducer from "./store/reducer"

// 辅助函数Provider可以把store关联到React
const store = createStore(reducer, applyMiddleware(thunk))

ReactDOM.render(
  // 用Provider组件包裹着App组件,store作为props值传入Provider。
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById("root")
)

reportWebVitals();

 好了以上就是redux准备工作接下来就是到实际组件运用了

 


 在  src  目录下新建个 components 文件夹

然后创建两个组件 A组件、B组件,目录结构长这样:

 

a.jsx(A组件)

import React, { useState } from 'react';
function A({ saveArticle }) {
  const [article, setArticle] = useState()

  const handleArticleData = e => {
    setArticle({ // 添加数据
      ...article,
      [e.target.id]: e.target.value, // id用于添加那个字段
    })
  }

  const add = ()=> { // 保存数据
    saveArticle(article)
  }

  return (
    <div className="A">
      我是A组件
      <input
        type="text"
        id="title"
        placeholder="Title"
        onChange={handleArticleData}
      />
      <input
        type="text"
        id="body"
        placeholder="Body"
        onChange={handleArticleData}
      />
      <button onClick={add}>添加article</button>
    </div>
  );
}

export default A;

 

b.jsx(B组件)
import React from 'react';
function B({articles}) {
  const renderArticles = ()=> { // 渲染列表
    return articles.map(article => (
      <div key={article.id}>
        <span>标题:{article.title}</span>,
        <span>内容:{article.body}</span>
      </div>
    ))
  }

  return (
    <div className="B">
      我是B组件
      {renderArticles()}
    </div>
  );
}

export default B;

 

App页面做例子(src的App.js)里面引用A组件、B组件

import A from './components/a'
import B from './components/b'
import { connect } from "react-redux"
import { simulateHttpRequest } from "./store/actionCreators"

function App({ articles, saveArticle }) {
  return (
    <div className="App">
      <A articles={articles} saveArticle={saveArticle}/>
      <B articles={articles}/>
    </div>
  );
}

/*
mapStateToProps函数名可以随便改,
它从store中获取state值作为它的参数,返回了一个对象。
为了获取到store中的state,我们需要把 mapStateToProps() 作为connect函数的参数。
*/
const mapStateToProps = state => {
  return {
    articles: state.articles,
  }
}

/*
在这里我们从actionTypes.js中引入了 everything 。
然后创建了一个新的函数mapDispatchToProps ,
它接收dispatch作为参数。
*/
const mapDispatchToProps = dispatch => {
  return {
    saveArticle: article => dispatch(simulateHttpRequest(article)),
  }
}

// connect:组件App获得redux的store
export default connect(
  mapStateToProps,
  mapDispatchToProps
)(App)

 

最终页面长这样:
通过redux,A组件做了更新,B组件自动更新

 

 

来个总结:
个人感觉小项目直接用hook完事,redux看情况用,
本文尽量用最简洁的代码实现redux的效果,没整其他的玩意干扰本文核心内容
还有很多redux技术点其实没提到,感觉自己学会、通过文字表达让别人理解是两回事

参考文章:https://zhuanlan.zhihu.com/p/103420294

posted @ 2020-12-30 16:54  前端-大雄  阅读(152)  评论(0编辑  收藏  举报