React 学习笔记(二)

本文深入解析Redux工作原理及流程,涵盖状态管理、组件分类、中间件使用等,详解如何与React无缝集成,实现高效数据流管理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这篇学习主要是围绕Redux展开的..

宇宙惯例..github地址 ⭐⭐⭐

Redux

  • ReduxReact没关系 redux也可以用在其他框架里 甚至是原生的js代码也可以用

  • Redux的工作流程

    • 先上一图流(字丑莫介意..orz)
    • 先做好各种初始化工作 例如安装好Redux , 组件中引入 store 并定义好各个文件的配置 store.getState() 和当前state做绑定 在此不过多赘述了
    • //例如
      // store.index.js中 (store)
      import { createStore } from 'redux'
      import reducer from './reducer'
      const store = createStore(
        reducer
      )
      
      
      //reducer.js中
      
      //默认值
      const defaultState = {
        value: ''
      }
      export default = ( state = defaultState, action )=>{
        return state
      }
      复制代码
    1. 组件中定义一个action的对象
    • 通常为了更便于维护和管理 我们将要用到的action对象拆分成一个单独的 actionCreators.js文件 里面是一个一个的返回一个对象的函数 返回的对象有以下属性
      • type: 用于之后检测的标识值
      • 要传递更改的数据
    //例如
    //actionCreators.js中定义
    export const getChangeAction = (value) => ({
      type : 'change_value',
      value
    })
    //组件中定义实际要用的action对象
    import { getChangeAction } from './store/actionCreators'
    const action = getChangeAction('testValue)
    复制代码
    1. 组件中将定义好的action对象通过 store.dispatch()方法将其派发出去
    //例如
    store.dispatch(action)
    复制代码
    1. reducer.js
      • reducer.js 函数中利用 之前定义好的action.type对传递来的对象进行拦截

      需要注意的是 在进行数据的更改时 reducer里不能进行原始数据的更改 只能将数据进行一次深拷贝 将拷贝下来的数据更改 然后再返回给store 让它对数据进行更新

    //例如
    export default = ( state = defaultState, action )=>{
      if( action.tyle === 'change_value' ){
        const newState = JSON.parse(JSON.stringify(state))
        newState.value = action.value
        return newState
      }
      return state
    }
    复制代码
    1. 到目前为止 数据以及更新完毕 但是视图层还没有更新 所以我们现在应该去更新视图层 需要在组件里 调用 store.subscribe()这个方法用来监听store里数据的变化同时接受一个函数作为参数, 如果store发生变化就调用传进去的那个函数 所以我们可以这么写
    //在constructor里
    
    //不要忘记更改this指向
    this.handleStoreChange = this.handleStoreChange.bind(this)
    store.subscribe(this.handleStoreChange)
    
    //handleStoreChange函数
    handleStoreChange(){
      this.setState(store.getState())
    }      
    复制代码

    大功告成

  • react-redux

    • react-redux也是用来做数据管理的 只不过是利用了react本身的一些特性, 因为react是单向数据流 所以我们索性把store集成到所有组件的顶层组件里, 即 顶层的 props
    • Provider 上做关联 连接 store 内部组件都可以获取store上的内容了
    //入口文件中 (index.js)
    import { Provider } from 'react-redux'
    const App = (
      <Provider store={store} >
        <TodoList/>
      </Provider>
    )
    
    ReactDOM.render(App, document.getElementById('root'));
    
    复制代码
    • 子组件通过 connect 获取
      • connect的第二个括号就是组件本身 第一个口号里需要两个参数 这两个参数都是两个函数 两个映射关系
    //组件中
    //state 是 store里的数据
    // 这个映射的规则就是 把 store里的数据映射到当前的props上
    const mapStoreStateToProps = (storeState) => {
      return {
        inputValue : storeState.inputValue
      }
    }
    
    // store.dispatch 挂到 当前的props上
    const mapStoreDispatchToProps = (storeDispatch) => {
      return {
        changeInputValue(e){
          const action = {
            type : 'change_input_value',
            value: e.target.value
          }
          storeDispatch(action)
        }
      }
    }
    
    export default connect(mapStoreStateToProps , mapStoreDispatchToProps)(TodoList);
    复制代码
  • Redux-thunk 中间件

    • 这个中间件使得我们可以在action里返回一个函数 使得一些异步操作 比如 获取ajax请求可以从组件中抽离出去
// 使用了 redux-thunk 后 action不仅仅只能是一个对象了 还可以是一个函数
export const getTodo =  () =>{
  // 返回的函数中的第一个参数就是dispatch方法
  return (dispatch) =>{
    $.get('something..').then(res=>{
      console.log(res)
    }).catch(()=>{
      console.log('error');
    })
  }
}
复制代码
由于在 `action` 和 `store`之间是通过 `dispatch`这个方法来进行沟通的 , 所以`redux-thunk`这个中间件实际上就是对`dispatch`的一个封装, 或者一个升级, 最原始的`dispatch`只能返回一个对象 然后再把这个对象返回给`store`, 使用了 `redux-thunk`之后, 我们可以传给`dispatch`一个函数 , 他就会先自动执行一遍这个函数, 执行完了之后 再将处理后或者执行完函数后的结构返回给store<br/>
一图流, `midWare`就是中间件处理的位置
复制代码

  • 还有很多其他中间件就不一一枚举了..

组件分类

  • UI组件与容器组件 (傻瓜组件和聪明组件)
  • UI组件只负责样式
  • 例如 将demo用的 todolist拆分
const TodoListUI = (props) =>{
  return (
    <div style={{ margin: " 0 auto ", width: "400px", paddingTop: "150px" }}>
      <div style={{ margin: "10px" }}>
        <Input
          placeholder="todo"
          value={props.inputValue}
          style={{ width: "300px", marginRight: "10px" }}
          onChange={props.handleInputChange}
        />
        <Button onClick={props.handleBtnClick} type="primary">提交</Button>
      </div>
      <List
        style={{ margin: "10px", width: "300px" }}
        bordered
        dataSource={props.list}
        header='todo'
        renderItem={(item,index )=> <List.Item onClick={()=>{props.handleItemClick(index)}}>{item}</List.Item>}
      />
    </div>
  )
}
更多详情见 github.. todolist2.0里面的代码
复制代码
  • 容器组件负责逻辑 功能实现 与UI组件之间通过 props连接

  • 无状态组件

    • 只有render函数的组件
    • 优势是性能比较高 因为它就是一个函数 不需要有相关的生命周期初始化过程

转载于:https://juejin.im/post/5cd51e84e51d453a7e4c17f7

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值