手写Redux
html
文档
<!DOCTYPE html>
<html >
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="root">
<div id="title"></div>
<div id="content">0</div>
</div>
<script src="./redux-my.js"></script>
</body>
</html>
过程1
//redux 状态管理 把数据集中存放
//当前所有组件的状态
let state = {
title:{content:'你好',color:'red'},
content:{content:'哈哈',color:'green'}
}
function renderTitle() {
let title = document.getElementById('title');
title.innerHTML = state.title.content;
title.style.background = state.title.color;
}
function renderContent() {
let content = document.getElementById('content');
content.innerHTML = state.content.content;
content.style.background = state.content.color;
}
function renderApp(){
renderTitle();
renderContent();
}
renderApp();
过程2
//redux 状态管理 把数据集中存放
//当前所有组件的状态
// 上面的版本中 状态会被更改,任何组件都可以修改,这样会影响我们所有的代码,对其进行封闭
//这里还是可以改状态的
function createStore(){
let state = {
title:{content:'你好',color:'red'},
content:{content:'哈哈',color:'green'}
}
let getState = ()=>state;
return {
getState
}
}
let store = createStore()
//1.redux中不能直接操作状态
function renderTitle() {
let title = document.getElementById('title');
title.innerHTML = store.getState().title.content;
title.style.background = store.getState().title.color;
}
function renderContent() {
let content = document.getElementById('content');
content.innerHTML = store.getState().content.content;
content.style.background = store.getState().content.color;
}
function renderApp(){
renderTitle();
renderContent();
}
renderApp();
过程3:
//redux 状态管理 把数据集中存放
//当前所有组件的状态
// 上面的版本中 状态会被更改,任何组件都可以修改,这样会影响我们所有的代码,对其进行封闭
function createStore(){
let state = {
title:{content:'你好',color:'red'},
content:{content:'哈哈',color:'green'}
}
let getState = ()=>JSON.parse(JSON.stringify(state)); //返回拷贝对象
return {
getState
}
}
let store = createStore()
//1.redux中不能直接操作状态
function renderTitle() {
let title = document.getElementById('title');
title.innerHTML = store.getState().title.content;
title.style.background = store.getState().title.color;
}
function renderContent() {
let content = document.getElementById('content');
content.innerHTML = store.getState().content.content;
content.style.background = store.getState().content.color;
}
function renderApp(){
renderTitle();
renderContent();
}
renderApp();
过程4
//redux 状态管理 把数据集中存放
//当前所有组件的状态
// 上面的版本中 状态会被更改,任何组件都可以修改,这样会影响我们所有的代码,对其进行封闭
function createStore(){
let state = {
title:{content:'你好',color:'red'},
content:{content:'哈哈',color:'green'}
}
let getState = ()=>JSON.parse(JSON.stringify(state)); //返回拷贝对象
let dispatch = (action)=>{
switch (action.type) {
case 'CHANGE_TITLE_COLOR':
console.log(action.color)
state.title.color = action.color;
break;
}
}
return {
getState,
dispatch
}
}
let store = createStore()
setTimeout(function () {
store.dispatch({type:'CHANGE_TITLE_COLOR',color:'pink'})
renderApp()
},1000)
//1.redux中不能直接操作状态
//2.如果任意一个组件中想更新状态,需要派发一个动作 dispatch 实现状态更新的 方法
function renderTitle() {
let title = document.getElementById('title');
title.innerHTML = store.getState().title.content;
title.style.background = store.getState().title.color;
}
function renderContent() {
let content = document.getElementById('content');
content.innerHTML = store.getState().content.content;
content.style.background = store.getState().content.color;
}
function renderApp(){
renderTitle();
renderContent();
}
renderApp();
过程5:
//redux 状态管理 把数据集中存放
//当前所有组件的状态
// 上面的版本中 状态会被更改,任何组件都可以修改,这样会影响我们所有的代码,对其进行封闭
function createStore(){
let state = {
title:{content:'你好',color:'red'},
content:{content:'哈哈',color:'green'}
}
let getState = ()=>JSON.parse(JSON.stringify(state)); //返回拷贝对象
let dispatch = (action)=>{
switch (action.type) {
case 'CHANGE_TITLE_COLOR':
console.log(action.color)
state.title.color = action.color;
break;
}
}
return {
getState,
dispatch
}
}
let store = createStore()
setTimeout(function () {
store.dispatch({type:'CHANGE_TITLE_COLOR',color:'pink'})
renderApp()
},1000)
//1.redux中不能直接操作状态
//2.如果任意一个组件中想更新状态,需要派发一个动作 dispatch 实现状态更新的 方法
function renderTitle() {
let title = document.getElementById('title');
title.innerHTML = store.getState().title.content;
title.style.background = store.getState().title.color;
}
function renderContent() {
let content = document.getElementById('content');
content.innerHTML = store.getState().content.content;
content.style.background = store.getState().content.color;
}
function renderApp(){
renderTitle();
renderContent();
}
renderApp();
过程6:
//redux 状态管理 把数据集中存放
//当前所有组件的状态
// 上面的版本中 状态会被更改,任何组件都可以修改,这样会影响我们所有的代码,对其进行封闭
let initstate = {
title:{content:'你好',color:'red'},
content:{content:'哈哈',color:'green'}
}
function createStore(reducer){
let state;
let getState = ()=>{return JSON.parse(JSON.stringify(state))}; //返回拷贝对象
let dispatch = (action)=>{
state = reducer(state,action)
}
dispatch({type:'@INIT'})
return {
getState,
dispatch
}
}
function reducer(state=initstate,action){
switch (action.type) {
case 'CHANGE_TITLE_COLOR':
console.log(action.color)
//不要直接修改
//state.title.color = action.color;
return {...state,title: {...state.title,color:action.color}}
break;
}
return state;
//return initstate;
}
let store = createStore(reducer)
setTimeout(function () {
store.dispatch({type:'CHANGE_TITLE_COLOR',color:'pink'})
renderApp()
},1000)
//1.redux中不能直接操作状态
//2.如果任意一个组件中想更新状态,需要派发一个动作 dispatch 实现状态更新的方法
//3.中间有个状态缺失,reducer。为什么要有这个环节?我想复用createStore();逻辑都写在这里面那么导致,原文件会被不断的修改,需要将 用户的数据提取出来。
//4.每次更新状态,最好用一个新的状态对象覆盖掉,每次状态改了,记录一下,可以对比一下。,如果直接修改那它引用一样,对比就没有了。
function renderTitle() {
let title = document.getElementById('title');
title.innerHTML = store.getState().title.content;
title.style.background = store.getState().title.color;
}
function renderContent() {
let content = document.getElementById('content');
content.innerHTML = store.getState().content.content;
content.style.background = store.getState().content.color;
}
function renderApp(){
renderTitle();
renderContent();
}
renderApp();
过程7
//redux 状态管理 把数据集中存放
//当前所有组件的状态
// 上面的版本中 状态会被更改,任何组件都可以修改,这样会影响我们所有的代码,对其进行封闭
let initstate = {
title:{content:'你好',color:'red'},
content:{content:'哈哈',color:'green'}
}
function createStore(reducer){
let state;
let getState = ()=>{return JSON.parse(JSON.stringify(state))}; //返回拷贝对象
let dispatch = (action)=>{
state = reducer(state,action)
}
dispatch({type:'@INIT'})
return {
getState,
dispatch
}
}
function reducer(state=initstate,action){
switch (action.type) {
case 'CHANGE_TITLE_COLOR':
console.log(action.color)
//不要直接修改
//state.title.color = action.color;
return {...state,title: {...state.title,color:action.color}}
case 'CHANGE_CONOTENT_CONTENT':
console.log(action.content)
//不要直接修改
//state.title.color = action.color;
return {...state,content: {...state.content,content:action.content}}
}
return state;
//return initstate;
}
let store = createStore(reducer)
setTimeout(function () {
store.dispatch({type:'CHANGE_TITLE_COLOR',color:'pink'})
store.dispatch({type:'CHANGE_CONOTENT_CONTENT',content:'这是新值'})
renderApp()
},1000)
//1.redux中不能直接操作状态
//2.如果任意一个组件中想更新状态,需要派发一个动作 dispatch 实现状态更新的方法
//3.中间有个状态缺失,reducer。为什么要有这个环节?我想复用createStore();逻辑都写在这里面那么导致,原文件会被不断的修改,需要将 用户的数据提取出来。
//4.每次更新状态,最好用一个新的状态对象覆盖掉,每次状态改了,记录一下,可以对比一下。,如果直接修改那它引用一样,对比就没有了。
function renderTitle() {
let title = document.getElementById('title');
title.innerHTML = store.getState().title.content;
title.style.background = store.getState().title.color;
}
function renderContent() {
let content = document.getElementById('content');
content.innerHTML = store.getState().content.content;
content.style.background = store.getState().content.color;
}
function renderApp(){
renderTitle();
renderContent();
}
renderApp();
过程8
//redux 状态管理 把数据集中存放
//当前所有组件的状态
// 上面的版本中 状态会被更改,任何组件都可以修改,这样会影响我们所有的代码,对其进行封闭
let initstate = {
title:{content:'你好',color:'red'},
content:{content:'哈哈',color:'green'}
}
function createStore(reducer){
let state;
let listeners = []
let getState = ()=>{return JSON.parse(JSON.stringify(state))}; //返回拷贝对象
let dispatch = (action)=>{
state = reducer(state,action)
listeners.forEach(item=>item());
}
let subscribe = (fn) =>{
listeners.push(fn)
}
dispatch({type:'@INIT'})
return {
getState,
dispatch,
subscribe
}
}
function reducer(state=initstate,action){
switch (action.type) {
case 'CHANGE_TITLE_COLOR':
console.log(action.color)
//不要直接修改
//state.title.color = action.color;
return {...state,title: {...state.title,color:action.color}}
case 'CHANGE_CONOTENT_CONTENT':
console.log(action.content)
//不要直接修改
//state.title.color = action.color;
return {...state,content: {...state.content,content:action.content}}
}
return state;
//return initstate;
}
let store = createStore(reducer)
store.subscribe(renderApp);
store.subscribe(()=>{console.log('呵呵')});
setTimeout(function () {
store.dispatch({type:'CHANGE_TITLE_COLOR',color:'pink'})
},1000)
setTimeout(function () {
store.dispatch({type:'CHANGE_CONOTENT_CONTENT',content:'这是新值'})
},2000)
//1.redux中不能直接操作状态
//2.如果任意一个组件中想更新状态,需要派发一个动作 dispatch 实现状态更新的方法
//3.中间有个状态缺失,reducer。为什么要有这个环节?我想复用createStore();逻辑都写在这里面那么导致,原文件会被不断的修改,需要将 用户的数据提取出来。
//4.每次更新状态,最好用一个新的状态对象覆盖掉,每次状态改了,记录一下,可以对比一下。,如果直接修改那它引用一样,对比就没有了。
//5.每次状态更新后,需要手动调用renderApp,通过订阅后,状态更改后自动触发
function renderTitle() {
let title = document.getElementById('title');
title.innerHTML = store.getState().title.content;
title.style.background = store.getState().title.color;
}
function renderContent() {
let content = document.getElementById('content');
content.innerHTML = store.getState().content.content;
content.style.background = store.getState().content.color;
}
function renderApp(){
renderTitle();
renderContent();
}
renderApp();
过程9
//redux 状态管理 把数据集中存放
//当前所有组件的状态
// 上面的版本中 状态会被更改,任何组件都可以修改,这样会影响我们所有的代码,对其进行封闭
let initstate = {
title:{content:'你好',color:'red'},
content:{content:'哈哈',color:'green'}
}
function createStore(reducer){
let state;
let listeners = []
let getState = ()=>{return JSON.parse(JSON.stringify(state))}; //返回拷贝对象
let dispatch = (action)=>{
state = reducer(state,action)
listeners.forEach(item=>item());
}
let subscribe = (fn) =>{
listeners.push(fn)
return ()=>{
listeners = listeners.filter(l=>l!==fn);
}
}
dispatch({type:'@INIT'})
return {
getState,
dispatch,
subscribe
}
}
function reducer(state=initstate,action){
switch (action.type) {
case 'CHANGE_TITLE_COLOR':
console.log(action.color)
//不要直接修改
//state.title.color = action.color;
return {...state,title: {...state.title,color:action.color}}
case 'CHANGE_CONOTENT_CONTENT':
console.log(action.content)
//不要直接修改
//state.title.color = action.color;
return {...state,content: {...state.content,content:action.content}}
}
return state;
//return initstate;
}
let store = createStore(reducer)
store.subscribe(renderApp);
let unsub = store.subscribe(()=>{console.log('呵呵')});
setTimeout(function () {
store.dispatch({type:'CHANGE_TITLE_COLOR',color:'pink'})
},1000)
setTimeout(function () {
unsub();
store.dispatch({type:'CHANGE_CONOTENT_CONTENT',content:'这是新值'})
},2000)
//1.redux中不能直接操作状态
//2.如果任意一个组件中想更新状态,需要派发一个动作 dispatch 实现状态更新的方法
//3.中间有个状态缺失,reducer。为什么要有这个环节?我想复用createStore();逻辑都写在这里面那么导致,原文件会被不断的修改,需要将 用户的数据提取出来。
//4.每次更新状态,最好用一个新的状态对象覆盖掉,每次状态改了,记录一下,可以对比一下。,如果直接修改那它引用一样,对比就没有了。
//5.每次状态更新后,需要手动调用renderApp,通过订阅后,状态更改后自动触发
//6.隔2s我取消订阅,怎么做?
function renderTitle() {
let title = document.getElementById('title');
title.innerHTML = store.getState().title.content;
title.style.background = store.getState().title.color;
}
function renderContent() {
let content = document.getElementById('content');
content.innerHTML = store.getState().content.content;
content.style.background = store.getState().content.color;
}
function renderApp(){
renderTitle();
renderContent();
}
renderApp();
到此已经完成手写的过程,代码其实不难,难点就是我们对其的理解层面吧。
Redux中间件(redux-thunk)异步处理(ajax)
//actionCreators.js
export const getTodoList=(arr)=> {
/*return ()=>{
axios.get('http://localhost:3000/json/res.json')
.then((data) => {
const res = data.data;
initListAction(res);
})
}*/
return async ()=>{
let res =await axios.get('http://localhost:3000/json/res.json')
if(!res) return;
initListAction(res.data)
}
}
//TodoList组件修改生命周期
componentDidMount() {
const action = actions.getTodoList();
store.dispatch(action)
}
这样的话,我们将组件内部的功能全部拆分出去,并且这样也是为了将来让actions可以快速进行前端自动化测试。同样的我们发现我们可以使用async/await
更易于管理代码。
react-redux(必须掌握)
修改入口文件
import React from 'react';
import {Provider} from 'react-redux'
import ReactDOM from 'react-dom';
import TodoList from './redux-update/TodoList'
import store from './redux-update/store/index.js'
ReactDOM.render(
<Provider store={store}>
<TodoList></TodoList>
</Provider>
, document.getElementById('root'));
修改TodoList组件
import React,{Component} from 'react';
import {connect} from 'react-redux';
class TodoList extends Component{
constructor(props){
console.log(props)
super(props);
this.state = {}
}
render() {
return (
<div>
<div>
<input onChange={this.props.Hchange.bind(this)} value={this.props.name} type="text"/>
<button>提交</button>
</div>
<ul>
<li>DELL</li>
</ul>
</div>
);
}
}
const mapStateToProps = (state)=>{
return {
name:state.name,
list:state.list
}
}
//发布store.dispatch, props
const mapDispatchToProps = (dispatch)=>{
return {
Hchange(e){
const action = {
type:'change_input_value',
value:e.target.value
}
dispatch(action)
}
}
}
export default connect(mapStateToProps,mapDispatchToProps)(TodoList);
}store文件
import {createStore} from 'redux'
import reducer from './reducer'
const store = createStore(reducer);
export default store;
reducer文件
let initData={
name:'hello world',
list:[]
}
//reducer
export default (state=initData,action)=>{
if(action.type==='change_input_value'){
var newvalue = JSON.parse(JSON.stringify(state))
newvalue.name = action.value;
return newvalue;
}
return initData;
}
在这里大家要建立几个概念。首先在入口文件中将store
引入到整个组件中。其次在组件中通过connct
来进行连接入口传递Provider
的传来的store
数据。
注意在组件最后导出时,export default connect(参数1,参数2)(参数3)
这里千万要注意导出的对象要进行连接。参数1,为数据集合,参数2为actions集合,参数3为我们当前的组件名称。
总结:
在这里面,其实都是有很多的概念,相较Vue
的Vuex
确实挺绕,不过我们学习,就是这样,不断接受新的思想,也要和老的思想进行比较,到了最后位置我们可以发现我们的代码其实也不是很难,就是在理解基础上,有更新认识就会更好。在书写文章时,参才了太多的知识,感谢网络的力量。也感谢官方的支持。
文章参考:
https://www.jianshu.com/p/9baca3ca08fa
网友评论