React复习(8)

(1)创建项目

全局安装:nmp install -g create-react-app
查看版本:create-react-app --version

(2)组件化开发

其实react的项目跟vue的项目都差不多,index.js是入口函数,App.js是根组件;
挂载的原理跟我之前写过的vue项目也一样

把之前写过的Task练习按照组件化开发的模式分解,大概成这样
这其中的头部和尾部就是src目录下component的Header和Footer
只是简单的模拟一下组件化开发

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

ReactDOM.render(<App />,document.getElementById('root'));
//App.js
import React from 'react';
import Header from './components/Header';
import Footer from './components/Footer';
import TaskMain from './pages/Task';

class App extends React.Component {
  render() {
    return (
      <div>
        {/*Header*/}
        <Header></Header>
        {/*TaskMain*/}
        <TaskMain></TaskMain>
        {/*Footer*/}
        <Footer></Footer>
      </div>
    )
  }
}
export default App;
//Task->index.js
import React from 'react';
import AddTask from './components/AddTask'
import TaskList from './components/TaskList'

class TaskMain extends React.Component {
  state = {
    tasks: []
  }
  //添加     task为AddTask组件传来参数
  addTask = (task) => {
    const { tasks } = this.state
    //使任务不为空
    if (!task) {
      return
    }
    //使每个任务都有独立的时间
    let taskNew = { task: task, date: new Date().toLocaleTimeString() }
    // unshift 是新数组的长度 不是新的数组
    tasks.unshift(taskNew)
    this.setState({
      tasks: tasks,
    })
  }
  //删除
  deleteTask = (index) => {
    const { tasks } = this.state
    tasks.splice(index, 1)
    this.setState({
      tasks
    }, () => { })
  }
  render() {
    return (
      <div>
        <h1>Today Tasks : {this.state.tasks.length}</h1>
        <AddTask addTask={this.addTask} />
        <TaskList tasks={this.state.tasks} deleteTask={this.deleteTask} />
      </div>
    )
  }
}
export default TaskMain
//Task->components->AddTask.js
import React from 'react';
//添加任务组件
class AddTask extends React.Component {
  state = { task: '' }
  //输入框同步
  handelChange = (e) => {
    this.setState({
      task: e.target.value
    }, () => { })
  }
  handleAddTask = () => {
    const { task } = this.state
    this.props.addTask(task)
    this.setState({
      task: ''
    })
  }
  render() {
    return (
      <div>
        <input type="text" value={this.state.task} onChange={this.handelChange} />
        <button onClick={this.handleAddTask}>添加</button>
      </div>
    )
  }
}
export default AddTask


//Task->components->TaskItem.js
//单项任务组件
function TaskItem(props) {
  function handleDelete() {
    props.deleteTask(props.index)
  }
  return (
    <li>
      <span>{props.index + 1}--{props.task}--{props.date}</span>
      <button onClick={handleDelete}>delete</button>
    </li>
  )
}
export default TaskItem


//Task->components->TaskList.js
import TaskItem from "./TaskItem"
//任务列表组件
function TaskList(props) {
  return (
    <div>
      <ul>
        {
          //              item是一个对象
          props.tasks.map((item, index) => {
            return <TaskItem key={index} index={index} task={item.task} date={item.date} deleteTask={props.deleteTask} />
          })
        }
      </ul>
    </div>
  )
}
export default TaskList

(3)redux

由于真实项目十分庞大,所以组件间传递状态和值是一个很难解决的问题
这时用redux,它能利用store统一管理状态
下面是redux的具体工作流程和一个redux案例

 

 

store是一个仓库,里面有各种各样的方法
可以利用这些方法在store内管理状态
具体流程就是:
视图层想改变state时,先通过actionCreator产生action
接着用store.dispatch方法把action传给reducer
reducer根据action进行逻辑处理
生成新的state返回给store
最后再由store传给视图层进行渲染

//AppCountRedux.js
import {Component} from 'react'
import store from './store'
import {incrementAction,decrementAction} from './store/actionCreator'
class App extends Component {
  //store.getState()可以取到reducer中的返回值,同步数据
  state = { count:store.getState()}
  constructor(){
    super()
    this.state = {count:store.getState()}
    //监听,store里的reducer一旦产生了新值,就会调用this.asyncState
    store.subscribe(this.asyncState)
  }
  asyncState=()=>{
    //获取最新数据,同步到state里
    this.setState({count:store.getState()})
  }
  increment=()=>{
    //store.dispatch中的参数就是action,把它传给reducer
    //要加括号执行,因为action已经被封装成函数了
    store.dispatch(incrementAction())
  }
  decrement=()=>{
    store.dispatch(decrementAction())
  }
  render() { 
    return (
      <div>
        Clicked:{this.state.count} times
        <button onClick={this.increment}>+</button>
        <button onClick={this.decrement}>-</button>
      </div>
    );
  }
}
export default App;


//AppCountRedux(对象).js
//与上一段代码的主要差别在于reducer中的参数格式不同
import {Component} from 'react'
import store from './store'
import {incrementAction,decrementAction} from './store/actionCreator'
class App extends Component {
  //store.getState()可以取到reducer中的返回值,同步数据
  constructor(){
    super()
    this.state = store.getState()
    //监听,store里的reducer一旦产生了新值,就会调用this.asyncState
    store.subscribe(this.asyncState)
  }
  asyncState=()=>{
    //获取最新数据,同步到state里
    this.setState(store.getState())
  }
  increment=()=>{
    //store.dispatch中的参数就是action,把它传给reducer
    //要加括号执行,因为action已经被封装成函数了
    store.dispatch(incrementAction())
  }
  decrement=()=>{
    store.dispatch(decrementAction())
  }
  render() { 
    return (
      <div>
        Clicked:{this.state.count} times
        <button onClick={this.increment}>+</button>
        <button onClick={this.decrement}>-</button>
      </div>
    );
  }
}
export default App;


//actionCreator.js
//统一管理,增强action
//因为reducer不适合写副作用代码,所以都写到action里
import * as constant from './constant'

export const incrementAction = (payload) => {
  return {type :constant.INCREMENT,payload:payload}
}
export const decrementAction = () => ({type :constant.DECREMENT})


//constant.js
//维护常量
//因为actionCreator和reducer中都用到相同的变量而且必须保持一致
//所以用一个公共的js文件来维护常量
export const INCREMENT = 'increment'
export const DECREMENT = 'decrement'


//store->index.js
import {createStore} from 'redux'
import  reducer from './reducer'
//创建仓库
//store本身只是一个仓库,它要调用reducer这个帮手来完成工作
//逻辑代码都在reducer中写
const store = createStore(reducer)
export default store


//reducer.js
import * as constant from './constant'
//默认state值
//数字格式
const defaultState = 0 
//对象格式
const defaultState = {count : 0}
//reducer实际就是一个纯函数
//第一个参数是状态;第二个action
//接收view层中dispatch发送的action,利用action中的值来进行判断处理
//action返回值是一个对象
const reducer = (state = defaultState,action) =>{
  switch(action.type){
    case constant.INCREMENT:
      //数字格式
      return state+1
      //此处的返回对象并不是在默认值的内存空间上更改值
      //而是新开辟了一块空间,创造一个新的对象
      return {count:state.count+1}
    case constant.DECREMENT:
      return state-1
      return {count:state.count-1}
    default:
      return state
  }
}
export default reducer
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

无非是我

不必打赏,欢迎指正

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值