1. redux如何使用
Redux是一个状态管理工具,在react-redux中有一个顶层组件Provider,里面有一个属性store,这个store是全局的,每个组件都可以访问,每个组件中在react-redux中 有一个connect并与全局的store进行连接,action中dispatch用于触发reducers函数,reducers接受两个参数,一个state,一个action,返回新的state,从而进行数据更新。
例子:使用redux实现一个简单的todolist的代码。
(1) 首先创建store文件夹,下面的index.js,把store当作一个仓库,用来存储数据。
import reducer from './reducer';
import thunk from 'redux-thunk';
const composeEnhancers =
window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ ?
window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({}) : compose;
const enhancer = composeEnhancers(
applyMiddleware(thunk)
);
const store = createStore(reducer, enhancer);
export default store;
(2) 在src下创建todolist.js
import 'antd/dist/antd.css';
import store from './store/index.js';
import TodoListUI from './TodoListUI.js'
import { getInputChangeAction, getAddItemAction, getDeleteItemAction } from './store/actionCreators.js'
class TodoList extends Component {
constructor (props) {
super(props);
this.state = store.getState();
this.handleInputChange = this.handleInputChange.bind(this);
this.handleStoreChange = this.handleStoreChange.bind(this);
this.handleBtnClick = this.handleBtnClick.bind(this);
this.handelItemDelete = this.handelItemDelete.bind(this);
store.subscribe(this.handleStoreChange)
}
render() {
return (
<TodoListUI
inputValue = {this.state.inputValue}
handleInputChange = {this.handleInputChange}
handleBtnClick = {this.handleBtnClick}
handelItemDelete = {this.handelItemDelete}
list = {this.state.list}
></TodoListUI>
)
}
handleInputChange(e) {
// const action = {
// type: CHANGE_INPUT_VALUE,
// value: e.target.value
//}
const action = getInputChangeAction(e.target.value)
store.dispatch(action)
}
handleStoreChange() {
this.setState(store.getState(
))
}
handleBtnClick() {
// const action = {
// type: ADD_TODO_ITEM
// }
const action = getAddItemAction();
store.dispatch(action)
}
handelItemDelete(index) {
// const action = {
// type: DELETE_TODO_ITEM,
// index
// }
const action = getDeleteItemAction(index)
store.dispatch(action)
}
}
export default TodoList;
(3) 在src下创建todoitem.js
import PropTypes from 'prop-types';
class TodoItem extends Component {
constructor (props) {
super(props);
//当组件state,props 的发生变化时,render函数就会重新执行
this.handleClick = this.handleClick.bind(this); //改变this指向
}
render() {
const {content, test} = this.props;
return <div onClick = {this.handleClick}>
{test}_{content}
</div>
}
//shanchu 子组件调用父组件的方法 去删除父组件的内容
handleClick () {
//alert(this.props.index);
//在子组件里面调用父组件的方法 调用父组件传递给子组件的方法;
const {deleteitem, index} = this.props;
deleteitem(index);
}
}
//对类型做校验 要求父组件给子组件传值的时候 值得类型式什么
TodoItem.propTypes = {
test: PropTypes.string.isRequired,
content: PropTypes.string,
handleClick: PropTypes.func,
index: PropTypes.number
}
// oneOfType 或者
//如果父组件没有向子组件传值,给的默认值
TodoItem.defaultProps = {
test: 'hellow world'
}
export default TodoItem;
(4)在src下面创建TodoListUI.js,通过antd引入ui组件。
import { Input, Button, List } from 'antd';
const TodoListUI = (props) => {
return (
<div style = {{marginTop: 10, marginLeft: 10}}>
<div>
<Input
value = {props.inputValue}
placeholder = 'todo indo'
style = {{width: 300,marginRight: 10}}
onChange = {props.handleInputChange}
></Input>
<Button type='提交' onClick = {props.handleBtnClick}>提交</Button>
</div>
<List bordered
dataSource = {props.list}
style = {{width: 300, marginTop: 10}}
renderItem = {(item, index) => (<List.Item
onClick = {() => {
props.handelItemDelete(index)
}}
>{item}</List.Item>)}
></List>
</div>
)
}
export default TodoListUI;
(5) 在store下创建actionCreators.js
通过判断actionType的type值,处理事件的方法
export const getInputChangeAction = (value) => ({
type: CHANGE_INPUT_VALUE,
value
})
export const getAddItemAction = (value) => ({
type: ADD_TODO_ITEM,
value
})
export const getDeleteItemAction = (index) => ({
type: DELETE_TODO_ITEM,
index
})
(6)在store下创建actionType.js
export const ADD_TODO_ITEM = 'add_todo_item';
export const DELETE_TODO_ITEM = 'delete_todo_item';
(7)在store下创建reducer.js
const defaultState = {
inputValue: '123',
list: [1, 2] //默认数据
}
//reducer可以接收state但是不能修改state
export default (state = defaultState, action) => {
if (action.type === 'change_input_value') {
const newState = JSON.parse(JSON.stringify(state));
newState.inputValue = action.value;
return newState;
}
if (action.type === 'add_todo_item') {
const newState = JSON.parse(JSON.stringify(state));
newState.list.push(newState.inputValue);
newState.inputValue = ''
return newState;
}
if (action.type === 'delete_todo_item') {
const newState = JSON.parse(JSON.stringify(state));
newState.list.splice(action.index, 1);
return newState;
}
return state;
}
最后在index.js中可以引入我们的todolist.js的组件
import ReactDOM from 'react-dom';
import Todolist from '../src/Todolist.js';
import * as serviceWorker from './serviceWorker';
//组件的拆分
ReactDOM.render( < Todolist / > , document.getElementById('root'));
serviceWorker.unregister();
2. redux-saga如何使用
Effect 是一个javaScript对象,可以通过yield传达给sagaMiddleware进行执行,我们用了redux-saga,所有的effect 都必须被yield才会执行eg :yield call(fetch, url)Call:call 主要是触发某个动作Put:触发某个action,作用和dispatch相同:Select:作用和redux thunk 中的getstate相同。可以通过yield select 来获取当前state中的某些字段Take:等待dispatch匹配某个action。
网友评论