react-project
熟悉react项目
团队协作github
react 项目复习
start
- 官方脚手架: create-react-app
- npm start 开启调试环境
- localhost:3000查看调试页面(默认端口)
mongo/node(Express)
- Express
- mongodb (使用依赖mongoose)
const express = require('express')
const mongoose = require('mongoose')
// 链接mongo
const DB_URL = 'mongodb://localhost:27017'
mongoose.connect(DB_URL)
mongoose.connection.on ('connected',function(){
console.log("success 表示连接成功")
})
//创建 表 及其字段
const User = mongoose.model('user',new mongoose.Schema({
user:{type:String,require:true},
age:{type:Number,require:true}
}))
//新增数据
User.create({
name:'ZF',
age:18
},function(err,doc){
if(!err){
console.log("新增数据成功",doc)
}else{
console.log(err)
}
})
//查找数据
app.get('/data',function(req,res){
User.find({},function(err,doc){
res.json(doc)
})
})
//删除数据 age:18
User.remove({age:18},function(err,doc){
console.log(doc)
})
//更新数据
User.update({'user':'xiaoming'},{'$set':{age:26}},function(err,doc){
console.log(doc)
})
const app = express();
app.get('/',function(req,res){
res.send('<h1>HELLO </h1>')
})
app.listen(9000,function(){
console.log("port 9093")
})
- state ,this.setState 是返回新的状态,不是直接修改值
- props
- 事件
绑定事件
1. 在constructor 里面绑定
是将this 强制绑定在class上
2. 使用箭头函数
<button onClick ={()=>this.handleChange()> </button>
3. 函数书写成箭头函数的形式
redux
- store 管理所有人的状态,记录所有state
- 需要改变的时候,需要做使用dispatch, 做什么是action
- 处理变化的是reducer 拿到旧的state和action,生成新的state
redux 使用方法
- 通过reducer 新建store ,通过 store.getState 获取状态
- 状态需要变更使用store.dispatch(action) 来修改状态
- reducer函数接收state和action,返回新的state,使用store.subscribe监听每次修改
reducer
function counter (state = 0,action){
switch(action.type){
case '1':
return state-1;
case ....
}
}
新建store
const store = createStore(counter);
如使用redux
import {createStore } from 'redux'
//1. 新建 store
//通过reducer建立
reducer
function counter (state = 0,action){
switch(action.type){
case '1':
return state-1;
case ....
}
}
//新建store
const store = createStore(counter);
//获取state
const init = store.getState() ;
//订阅事件
function listener(){
const current = store.getState();
console.log("current")
}
store.subscribe(listener);
//派发事件 传递action
store.dispatch({type:'1'})
Redux 如何和react 一起使用
- 不使用setState直接去改变,而是使用 store.dispatch 方法传递给组件,内部调用setState
- Subscribe 订阅render函数,每次修改都重新渲染
- redux 相关内容全部独立成一个单独的redux文件
//新建 ***.redux.js文件
import axios from 'axios'
//定义成常量,下面的reducer 就可以直接使用
const USER_LIST = 'USER_LIST'
const initState={
userList:[]
}
//reducer
export function chatuser(state= initState,action){
switch(action.type){
case USER_LIST:
return {...state,userList:action.payload}
default :
return state
}
}
//action creator 生 action
export function userList(data){
return {type:USER_LIST,payload:data}
}
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import { counter } from './index.redux'
const store = createStore(counter)
function render(){
ReactDOM.render(<App store={store}/>, document.getElementById('root'));
}
render();
store.subscribe(render) ;//是为了改变之后还会执行render 函数,不用每次手动更新
因为是通过store传递,所以子组件就可以使用 const store = this.props.store
const data = store.getState() 获取状态
子组件
import React from 'react'
import { userList} from './***.redux.js'
class App extends React.Component {
render(){
const store = this.props.store
const data = store.getState()
return (
<div>
<button onClick = {()=>store.dispatch(userList())}> 获取列表</button>
</div>
)
}
}
组件解耦
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import { counter,userList } from './index.redux'
const store = createStore(counter)
function render(){
ReactDOM.render(<App store={store} userList ={userList }/>, document.getElementById('root'));
}
render();
store.subscribe(render) ;//是为了改变之后还会执行render 函数,不用每次手动更新
因为是通过store传递,所以子组件就可以使用 const store = this.props.store
const data = store.getState() 获取状态
子组件App.js
import React from 'react'
<!--import { userList} from './***.redux.js'-->
class App extends React.Component {
render(){
const store = this.props.store
const data = store.getState();
const userList = this.props.userList
return (
<div>
<button onClick = {()=>store.dispatch(userList())}> 获取列表</button>
</div>
)
}
}
异步处理
- Redux 处理异步,需要使用redux-thunk 插件
- Npm install redux-devtools-extension 并且开启异步处理
- 使用react -redux 链接react 和 redux
步骤:
- 安装redux-thunk 插件 npm install redux-thunk --save
- 使用applyMiddleware 开启thunk 中间件
在index里面开启 index.js
import React from 'react';
import ReactDOM from 'react-dom';
import { createStore,applyMiddleware} from 'redux'
import thunk from 'redux-thubk' // 注意不需要大括号
import App from './App';
import { counter,userList } from './index.redux'
//注意改变
const store = createStore(counter,applyMiddleware(thunk))
function render(){
ReactDOM.render(<App store={store} userList ={userList }/>, document.getElementById('root'));
}
render();
store.subscribe(render) ;//是为了改变之后还会执行render 函数,不用每次手动更新
因为是通过store传递,所以子组件就可以使用 const store = this.props.store
const data = store.getState() 获取状态
在 ***.redux.js 里面添加一个异步函数,使得可以返回一个函数,就是 getUserList 函数
//新建 ***.redux.js文件
import axios from 'axios'
//定义成常量,下面的reducer 就可以直接使用
const USER_LIST = 'USER_LIST'
const initState={
userList:[]
}
//reducer
export function chatuser(state= initState,action){
switch(action.type){
case USER_LIST:
return {...state,userList:action.payload}
default :
return state
}
}
//action creator 生 action
function userList(data){
return {type:USER_LIST,payload:data}
}
export function getUserList(type){
return dispatch=>{
axios.get(`/user/list?type=${type}`)
.then(res=>{
if(res.data.code === 0){
dispatch(userList(res.data.data))
}
})
}
}
- 使得 action 可以返回函数,
redux 状态管理 chrom 调试工具 Redux-Devtools
使用react-redux
- npm install react-redux --save
- 忘记subscribe 记住reducer,action和dispatch
- React-redux 提供Provider 和 connect 两个接口来链接
具体使用
- Provider组件在应用的最外层,只传入store即可,只用一次 index.js
import React from 'react'
import ReactDom from 'react-dom'
import { createStore,applyMiddleware,compose} from 'redux'
import thunk from 'redux-thunk'
import {Provider} from 'react-redux'
import {BrowserRouter} from 'react-router-dom'
import App from './app'
import reducers from './reducer'
import './config'
import './index.css'
const store = createStore(reducers,compose(
applyMiddleware(thunk),
window.devToolsExtension?window.devToolsExtension():f=>f
))
ReactDom.render(
(<Provider store={store}>
<BrowserRouter>
<App></App>
</BrowserRouter>
</Provider>),
document.getElementById("root")
)
- Connect负责从外部获取组件需要的参数,也可以使用装饰器方式写 子组件App.js,注意不对比不同之处
import React from 'react'
impirt { connect} from 'react-redux'
import { userList} from './***.redux.js'
class App extends React.Component {
render(){
const store = this.props.store
const data = this.props.data;
const userList = this.props.userList
return (
<div>
<button onClick = {userList}> 获取列表</button>
</div>
)
}
}
//需要的数据 ,第一个参数
const mapStatetoProps=(state)=>{
return {data:state}
}
//第二个参数需要的action creator
const actionCreators = {userList}
//这样使得新生成的App组件 使用props 来获取一切,直接使用
App = connect(mapStatetoProps,actionCreators)(App)
//connect 是高阶组件,生成一个组件
export default App;