重要api
let store = Redux.createStore(函数)
function 函数(之前的状态,操作) {
reutrn 新的状态
}
使用valila配合Redux实现一个计数功能
- 首先创建一个store,store里初始值设置为0
function render() {
let app = document.querySelector("#app");
app.innerHTML = `
你点击了${store.getState()}次
`;
}
function stateChange(state = 0, action) {
if (action.type === "add") {
let newState = state + 1;
return newState;
} else {
return state;
}
}
let store = Redux.createStore(stateChange);
render();
- 给按钮绑定一个事件,事件触发的的时候调用store.dspatch
window.add = () => {
store.dispatch({ type: "add", payload: 1 });
};
- 重新render然后通过store.subscribe监听
render();
store.subscribe(render);
完整代码: https://codesandbox.io/s/compassionate-butterfly-u1ut4
使用React+Redux实现一个计数功能
- 创建项目
create-react-app my-project
- 安装redux
yarn add redux
- 创建store
- index.js
import { createStore } from 'redux'
const stateChange = (state = 0, action) => {
if (action.type === "add") {
let newState = state + action.payload;
return newState;
} else {
return state;
}
}
const store = createStore(stateChange)
- 将store通过props传递给App
- index.js
function render() {
ReactDOM.render( , document.getElementById('root'));
}
- App.js
import React, { Component } from 'react';
class App extends Component {
render() {
return (
你点击了{this.props.value}次
)
}
}
export default App;
- 因为我们的App.js里的store是通过index.js传进来,所以我们的点击事件不能直接出发store的修改,也要通过props传进一个方法,然后点击是调用props的方法,而props里的方法直接对store修改
- index.js
function add1() {
store.dispatch({ type: 'add', payload: 1 })
}
function minus1() {
store.dispatch({ type: 'add', payload: -1 })
}
function addIfOdd() {
console.log('hhh')
if (store.getState() % 2 === 1) {
store.dispatch({ type: 'add', payload: 1 })
}
}
function addSync() {
setTimeout(() => {
store.dispatch({ type: 'add', payload: 1 })
}, 2000)
}
function render() {
ReactDOM.render(, document.getElementById('root'));
}
render()
store.subscribe(render)
- App.js
import React, { Component } from 'react';
class App extends Component {
add1 = () => {
this.props.add1()
}
minus1 = () => {
this.props.minus1()
}
addIfOdd = () => {
this.props.addIfOdd()
}
addSync = () => {
this.props.addSync()
}
render() {
return (
你点击了{this.props.value}次
)
}
}
export default App;
问题:上面的代码我们的store里的方法和state通过父组件传给子组件,然后子组件触发父组件的事件再通知给父组件,这样的数据传递很复杂
改进:一开始就把store传进来
function render() {
ReactDOM.render(, document.getElementById('root'));
}
class App extends Component {
add1 = () => {
this.props.store.dispatch({ type: 'add', payload: 1 })
}
}
虽然我们改进后的代码不用再通知父组件了,但是如果我们有多层组件的嵌套,还需要数据一直从根组件往下一级一级的传下去,还是很复杂
使用React+Redux+React-Redux来解决数据层层传递的问题
- 安装react-redux
yarn add react-redux
- 根组件里引入Provider,并将Provider作为根标签
import { Provider } from 'react-redux'
ReactDOM.render(
,
document.getElementById('root')
);
- 将state里的默认值改写为对象
const stateChange = (state = { n: 1 }, action) => {
if (action.type === "add") {
let newState = { n: state.n + action.payload };
return newState;
} else {
return state;
}
}
- 子组件引入connect
import { connect } from 'react-redux'
class App extends Component {
render() {
return (
你点击了{this.props.n}次
)
}
}
function getPartialStore(state) {
return {
n: state.n
}
}
// actionCreator参数可以是对象也可以是函数
// 对象写法
const actionCreator = {
add1() {
return {
type: 'add',
payload: 1
}
}
}
// 函数写法
function actionCreator(dispatch) {
return {
add1: () => dispatch({ type: 'add', payload: 1}),
minus1: () => dispatch({ type: 'add', payload: -1 })
}
}
export default connect(getPartialStore, actionCreator)(App);
connect: (需要获取的部分store,你要生成哪些action)(当前组件)
然后里面获取store里的数据直接通过this.props.需要的数据名
redux中间件
中间件是store和action中间,所以只有redux才有中间件,也就是处理dispatch的接口的异步过程