AcWing
  • 首页
  • 活动
  • 题库
  • 竞赛
  • 应用
  • 更多
    • 题解
    • 分享
    • 商店
    • 问答
    • 吐槽
  • App
  • 登录/注册

Web应用课——5.4 React——Redux(redux-app)

作者: 作者的头像   ._675 ,  2023-05-26 14:47:07 ,  所有人可见 ,  阅读 45


0


屏幕截图 2023-05-26 112646.png
屏幕截图 2023-05-26 112733.png
屏幕截图 2023-05-26 144525.png
index.js

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import { configureStore } from '@reduxjs/toolkit';
import { combineReducers } from '@reduxjs/toolkit';
import { Provider } from 'react-redux';
import App from './components/app';

//redux里面的每一个状态一般值是存到叶节点上,每一个内部节点都是用来关联叶节点的值

//定义一个reducer,这个函数会传入两个值,第一个是上一个state的值,第一次调用的时候会传入一个undefined,我们需要给他一个默认值,可以看成state的一个初始值,
//另外还会传入一个参数action,action是一个对象,里面有一个名字叫type,
const f1=(state=0,action)=>{
  switch(action.type){
    case 'add':
      // return state+1;
      // return 可以传参数,例如state不加1了想加一个具体值,由于传入的action是一个对象,所以这里action可以传一个值
      return state+action.value;
    case 'sub':
      // return state-1;
      return state-action.value;
    default:
      return state;
  }
};

const f2=(state=":",action)=>{
  switch(action.type){
    case 'concat':
      return state+action.character;
    default:
      return state;
  }
};

// 将两个reducer合并成一个reducer,他初始的话就是一个字典,f3的作用主要是将f1和f2组合起来
//组合两个值的方法就是把子节点f1f2的值作为他的父节点值的字典,对象里面的两个属性
// const f3=(state={},action)=>{
//   return{
//     f1:f1(state.f1,action),
//     f2:f2(state.f2,action),
//   }
// };

const f3=combineReducers({
  number:f1,
  string:f2,
})


//假设当前树里面只有一个节点,我们要把当前节点构建成一个树
//store就是将函数f1构建成一颗状态树,传入一个对象,
const store=configureStore({
  // reducer: f1
  reducer: f3
});

//订阅函数,可以让我们在每次dispatch执行完之后都可以执行一个函数
// store.subscribe(()=>{console.log(store.getState())});

// //修改这个值,dispatch是传入一个action,action就是一个对象,对象里面只用到了type,所以这个对象里面只有一个值叫type
// //这个函数的意思就是将action这个参数传递给我们整棵树的所有的reducer函数,他会调用整棵树所有的reducer函数
// //当前树里只有一个reducer函数就是f1,所以我们执行这句话的话就会调用一下f1,然后将{type:"add"}传给f1的action
// //调用完之后可以看到action的值是add,所以会执行state+1,那么它会返回state+1,返回的这个值就会作为state的新值
// //这个action其实就是我们传入的这个值
// store.dispatch({type:"add",value:1});
// store.dispatch({type:"add",value:1});
// store.dispatch({type:"add",value:1});
// store.dispatch({type:"sub",value:1});
// store.dispatch({type:"sub",value:1});
// store.dispatch({type:"concat",character:"aaa"});
// store.dispatch({type:"concat",character:"xxx"});



//求整颗树的值
// console.log(store.getState());

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  //如果想在项目里面用到redux的话,就需要用provider将整个项目包含起来
  //provider一定要提供一个属性store,这个store就是存我们刚刚创建的store
  <Provider store={store}>
    <App />
  </Provider>
);

app.jsx

import React, { Component } from 'react';
import Number from './number';
import String from './string';

class App extends Component {
    state = {  } 
    render() { 
        return (
            // app里有两个组件
            <React.Fragment>
                <Number />
                <hr />
                <String/>
            </React.Fragment>
        );
    }
}

export default App;

number.jsx

import React, { Component } from 'react';
import { connect } from 'react-redux';

class Number extends Component {
    state = {  } 

    handleClick=()=>{
        this.props.concat('y');
    }
    render() { 
        console.log(this.props);
        return (
            <React.Fragment>
                <h3>Number:</h3>
                <div>{this.props.number}</div>
                <button onClick={this.handleClick}>添加</button>
            </React.Fragment>
        );
    }
}
//在组件里面像是store的值,用connect
//connect返回一个函数,可以将我们自己定义的组件传入进去然后返回一个组装好的组件
//组装的话,可以组装两个东西,第一个是可以将我们的值组装到我们组件的props这个属性里面
//mapStateToProps将我们store里的state这个值绑定到我们组件的props属性上
//传入的第一个函数有两种取值,第一个是state,这个state就是我们store getState之后的结果,也就是我们整个状态树的树结构,状态树的树结构这个值是不包含reducer函数的,值包含state值
//第二个属性是props也就是我们原始的props
const mapStateToProps=(state,props)=>{
    // 返回一个字典,返回一个对象,对象里面我们可以定义一下,比如说我们想取出state里面的number这个值,然后我们把number这个值赋到哪个属性上,可以把他赋到number这个属性上
    return{
        number:state.number,
    }
}

//修改
//将dispatch这个函数映射到props里面,只会在创建的时候调用一次
const mapDispatchToProps={
    // 在number里面修改string的值 concat是一个函数他最后会返回一个对象,这个对象就是我们dispatch里面用到的action,action就是我们传入的包含type的对象,所以他最后会返回一个对象这个对象里面一定要包含一个action
    //在string里添加一个字符,修改string的话,要用到'concat'这个字符串,,concat可以传入一个变量c,c表示我们要添加的字符,要用action的哪个属性这里在传的时候就要用哪个属性
    concat:(c)=>{
        return {
            type:"concat",
            character:c,
        }
    }
}


//将number值绑定到组件上要用到connect函数,connect(mapStateToProps)函数返回值会返回一个函数,函数可以将我们Number这个组件作为输入参数,它会返回一个新的组件,这个新的组件就会将我们state里的number(右边state.number)绑定到我们当前组件的props里面的number(左边number)这个属性上
export default connect(mapStateToProps,mapDispatchToProps)(Number);

string.jsx

import React, { Component } from 'react';
import { connect } from 'react-redux';

class String extends Component {
    state = {  } 

    handleClickAdd=()=>{
        this.props.add(10);
    }

    handleClickSub=()=>{
        this.props.sub(1);
    }

    render() { 
        console.log(this.props);
        return (

            <React.Fragment>
                <h3>String:</h3>
                <div>{this.props.string}</div>
                <button onClick={this.handleClickAdd}>加</button>
                <button onClick={this.handleClickSub}>减</button>
            </React.Fragment>
        );
    }
}

const mapStateToProps=(state,props)=>{
    // 返回一个字典,返回一个对象,对象里面我们可以定义一下,比如说我们想取出state里面的number这个值,然后我们把number这个值赋到哪个属性上,可以把他赋到number这个属性上
    return{
        string:state.string,
    }
}

const mapDispatchToProps={
    add:(x)=>{
        return {
            type:"add",
            value:x,
        }
    },
    sub:(x)=>{
        return{
            type:"sub",
            value:x,
        }
    }
}

//将number值绑定到组件上要用到connect函数,connect(mapStateToProps)函数返回值会返回一个函数,函数可以将我们Number这个组件作为输入参数,它会返回一个新的组件,这个新的组件就会将我们state里的number(右边state.number)绑定到我们当前组件的props里面的number(左边number)这个属性上
export default connect(mapStateToProps,mapDispatchToProps)(String);

0 评论

你确定删除吗?

© 2018-2023 AcWing 版权所有  |  京ICP备17053197号-1
用户协议  |  隐私政策  |  常见问题  |  联系我们
AcWing
请输入登录信息
更多登录方式: 微信图标 qq图标 qq图标
请输入绑定的邮箱地址
请输入注册信息