React
reduc 是(React全家桶)的核心成员
新建项目怎么使用 redux和react-redux?
- 新建文件夹store
- 在 store文件夹内新建一个index.js文件
- 在 index.js文件中我们需要引入{createStore,combineReducers,applyMiddleWare}三个函数
- 随后安装 redux-thunk插件
- 使用 createStore创造 store对象,
- createStore的第一个参数是:需要我们传入 根reducer(所有 reducer.js纯函数中的更新数据的方法,是通过combineReducers产生的)
- createStore的第二个参数是:applyMiddleWare(reduxThunk) // 一个用于使用异步操作的插件
- 以后每新增一个reducer我们都要在这个文件里引入,然后放到combineReducers的参数中
- 在 index.js文件中我们需要引入{createStore,combineReducers,applyMiddleWare}三个函数
- 在 store文件夹内新建一个index.js文件
- 一般还会有actions.js reducers.js action-types.js 这个三个文件
index.js
import {createStore,combineReducers,applyMiddleware} from 'redux'
import reduxThunk from 'redux-thunk' // 用于使用异步操作的插件
import {colorReducer,countReducer} from './reducers.js'
let rootReducer = combineReducers({
colorReducer,countReducer
});
let store = createStore(rootReducer,applyMiddleware(reduxThunk));
// export default {store}
// 使用方想要通过解构的方式 获取store 是不支持的
export default store
- 在新建项目的时候
- 一般情况下,需要我们去创造一个对应的 reducers.js纯函数文件
- 然后把你创建的这个 reducers.js中的{colorReducer,countReducer}用来更新数据的方法, 作为 combineReducers实参,引入到 combineReducers的函数方法中。
- 然后再去对应的添加一个actions文件
- 一般情况下,需要我们去创造一个对应的 reducers.js纯函数文件
reducers.js
import * as types from './action-types.js'
// 纯函数
export function colorReducer(state,action){
if(!state){
return{
color:'blue'
}
}
switch(action.type){
case types.COLOR:
return{
...state,
color:action.color
}
break;
default:
return state
break;
}
}
export function countReducer(state,action){
if(!state){
return{
count:0
}
}
switch(action.type){
case types.COUNT:
return{
...state,
coUNT:action.count
}
break;
default:
return state
break;
}
}
- 在新建项目的时候
- 一般情况下,需要我们去创造一个对应的 actions.js文件
- 然后把你创建的这个 actions.js中的
changeColor
,changeColor11
方法是由于用户操作触发执行,从而实现数据更新。
- 然后把你创建的这个 actions.js中的
- 一般情况下,需要我们去创造一个对应的 actions.js文件
actions.js
import {COLOR} from './action-types.js'
// import store from '../store/index.js'
export const changeColor = (str)=>{
return{
type:COLOR,
color:str
}
}
<-- 这个函数体里面我们用来进行对异步代码的编写 -->
export const changeColor11 = (str)=>{
return function(dispatch,getState){
<-- 这里的 dispatch,getState就是 store 里面对应的两个函数 -->
console.log(dispatch,getState);
// console.log(store.getState());
setTimeout(()=>{
dispatch({
type:COLOR,
color:str
})
},2000);
}
}
- 在创建 actions.js文件的之后
- 为了方便在有文件数据起冲突的时候可以快速更改,一般情况下,需要我们去创造一个对应的 action-types.js文件
- 该文件存储的都是一些常量
- 如:
import {COLOR} from './action-types.js'
,在 actions.js文件中,可以用action-types.js文件中创造的属性依据 type作为属性值,来判断在函数方法中需要数据更新的属性 - 如:
import * as types from './action-types.js
,在 reducers.js纯函数文件中,可以用 action-types.js文件中创造的属性依据 type作为属性值,来判断在函数方法中需要数据更新的属性
- 为了方便在有文件数据起冲突的时候可以快速更改,一般情况下,需要我们去创造一个对应的 action-types.js文件
action-types.js
export const COLOR = 'CHANGE_COLOR'
export const COUNT = 'CHANGE_COUNT'
- 创建完成之后,在根组件之中,我们使用 Provider(redux-react提供)组件包裹住我们的内容
- 然后给这个组件设置一个 store行内属性
- 行内属性 store值是:通过createStore产生的那个对象(store文件夹–>index.js)
- 然后给这个组件设置一个 store行内属性
react跟组件 index.js
import React from 'react';
import ReactDOM from 'react-dom';
import {Provider} from 'react-redux'
import store from '../store/index.js'
import Header from './header.js'
import Content from './content.js'
import Content2 from './content.js'
class App extends React.Component {
constructor() {
super();
}
render() {
return (<Provider store={store}>
{/* 是把 store赋值给了Provide的context,
使其所有的子孙组件都可以从其中获取数据 */}
<div className=''>
<Header/>
<Content/>
<Content2/>
</div>
</Provider>)
}
}
export default App
- 创建子组件组件
Hreder
,Content
- 对于所有的子孙组件;用
this.props
则可以到获取 store中的 state数据,同时需要使用connect(redux-react)处理当前组件,
- 对于所有的子孙组件;用
Header
import React from 'react';
import ReactDOM from 'react-dom';
import {connect} from 'react-redux'
class Header extends React.Component {
constructor() {
super();
}
render() {
return <div className=''>
<h1 style={{color:this.props.color}}>头部</h1>
</div>;
}
}
<-- 通过 connect方法,子组件封装 -->
Header = connect((state)=>{
return{
color:state.colorReducer.color
}
},(dispatch)=>{
return{
dispatch
}
})(Header)
export default Header
Content
import React from 'react';
import {connect} from 'react-redux';
import {changeColor,changeColor11} from '../store/actions.js'
import store from '../store/index.js';
class Content extends React.Component {
constructor() {
super();
}
fn(str){
this.props.dispatch(changeColor11(str));
}
render() {
return <div className=''>
<h2 style={{color:this.props.color}}>这是内容</h2>
<button
onClick={()=>{this.fn('red')}}
>red</button>
<button
onClick={()=>{this.fn('yellow')}}
>yellow</button>
</div>;
}
}
<-- 通过 connect方法,子组件封装 -->
Content = connect((state)=>{
return{
color:state.colorReducer.color,
}
},(dispatch)=>{
return{
dispatch
}
})(Content)
export default Content
Content2.js
- Content2.js相比起上面的 Content.js没有什么本质上的不同,只是把高阶函数 connect的第二个参数从
(dispatch)=>{return{dispatch}}
变为{changeColor:changeColor,changeColor11:changeColor11}
这样写可以使点击事件执行触发函数方法fn
,看上去更方便,然而却不利于理解。
import React from 'react';
import ReactDOM from 'react-dom';
import {connect} from 'react-redux';
import {changeColor,changeColor11} from '../store/actions.js'
import store from '../store/index.js';
class Content2 extends React.Component {
constructor() {
super();
}
fn(str){
this.props.changeColor11(str);
}
render() {
return <div className=''>
<h2 style={{color:this.props.color}}>这是内容</h2>
<button
onClick={()=>{this.fn('red')}}
>red</button>
<button
onClick={()=>{this.fn('yellow')}}
>yellow</button>
</div>;
}
}
<-- 通过 connect方法,子组件封装 -->
Content2 = connect((state)=>{
return{
color:state.colorReducer.color,
}
},{
changeColor,
changeColor11
})(Content2)
export default Content2