Reactjs 如何使用redux在todo列表中添加todo项
我已经为我的应用程序创建了Reactjs 如何使用redux在todo列表中添加todo项,reactjs,redux,react-redux,Reactjs,Redux,React Redux,我已经为我的应用程序创建了操作和减速器。我正在尝试创建一个新的todo,并希望使用redux将其保存在状态 action/index.js let taskID = 0; export const addTodo = text => { return { type: "ADD_TODO", text, id: taskID++ }; }; reducers/todos.js const todo = (state = {}, action) => { switch (ac
操作
和减速器
。我正在尝试创建一个新的todo,并希望使用redux
将其保存在状态
action/index.js
let taskID = 0;
export const addTodo = text => {
return { type: "ADD_TODO", text, id: taskID++ };
};
reducers/todos.js
const todo = (state = {}, action) => {
switch (action.type) {
case "ADD_TODO":
return {
id: action.id,
text: action.text,
status: false
};
default:
return state;
}
};
export default todo;
reducers/index.js
import { combineReducers } from "redux";
import todos from "./todos";
const todoApp = combineReducers({ todo });
export default todoApp;
index.js
import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
import registerServiceWorker from "./registerServiceWorker";
import "./index.css";
import { Provider } from "react-redux";
import { createStore } from "redux";
import todoApp from "./reducers/todos";
let store = createStore(todoApp);
ReactDOM.render(
<Provider store={store}><App /></Provider>,
document.getElementById("root")
);
registerServiceWorker();
从“React”导入React;
从“react dom”导入react dom;
从“/App”导入应用程序;
从“/registerServiceWorker”导入registerServiceWorker;
导入“/index.css”;
从“react redux”导入{Provider};
从“redux”导入{createStore};
从“/reducers/todos”导入todoApp;
let store=createStore(todoApp);
ReactDOM.render(
,
document.getElementById(“根”)
);
registerServiceWorker();
App.js
import React, { Component } from "react";
import logo from "./logo.svg";
import "./App.css";
import AppBar from "material-ui/AppBar";
import FloatingActionButton from "material-ui/FloatingActionButton";
import MuiThemeProvider from "material-ui/styles/MuiThemeProvider";
import * as strings from "./Strings";
import * as colors from "./Colors";
import styles from "./Styles";
import ContentAdd from "material-ui/svg-icons/content/add";
import Dialog from "material-ui/Dialog";
import FlatButton from "material-ui/FlatButton";
import * as injectTapEventPlugin from "react-tap-event-plugin";
import TextField from "material-ui/TextField";
import { List, ListItem } from "material-ui/List";
import { connect } from "react";
import { addTodo } from "./actions/index";
const AppBarTest = () =>
<AppBar
title={strings.app_name}
iconClassNameRight="muidocs-icon-navigation-expand-more"
style={{ backgroundColor: colors.blue_color }}
/>;
class App extends Component {
constructor(props) {
injectTapEventPlugin();
super(props);
this.state = {
open: false,
todos: [],
notetext: ""
};
this.handleChange = this.handleChange.bind(this);
}
handleOpen = () => {
this.setState({ open: true });
};
handleClose = () => {
this.setState({ open: false });
};
handleCreateNote = () => {
let todos = [...this.state.todos];
todos.push({
id: todos.length,
text: this.state.notetext,
completed: false
});
this.setState({ todos: todos }, () => {
// setState is async, so this is callback
});
this.handleClose();
};
handleChange(event) {
this.setState({ [event.target.name]: event.target.value });
}
_renderTodos() {
return this.state.todos.map(event => {
return (
<ListItem
primaryText={event.text}
key={event.id}
style={{ width: "100%", textAlign: "center" }}
onTouchTap={this._handleListItemClick.bind(this, event)}
/>
);
});
}
_handleListItemClick(item) {
console.log(item);
}
render() {
return (
<MuiThemeProvider>
<div>
<AppBarTest />
<FloatingActionButton
style={styles.fab}
backgroundColor={colors.blue_color}
onTouchTap={this.handleOpen}
>
<ContentAdd />
</FloatingActionButton>
<Dialog
open={this.state.open}
onRequestClose={this.handleClose}
title={strings.dialog_create_note_title}
>
<TextField
name="notetext"
hintText="Note"
style={{ width: "48%", float: "left", height: 48 }}
defaultValue={this.state.noteVal}
onChange={this.handleChange}
onKeyPress={ev => {
if (ev.key === "Enter") {
this.handleCreateNote();
ev.preventDefault();
}
}}
/>
<div
style={{
width: "4%",
height: "1",
float: "left",
visibility: "hidden"
}}
/>
<FlatButton
label={strings.create_note}
style={{ width: "48%", height: 48, float: "left" }}
onTouchTap={this.handleCreateNote}
/>
</Dialog>
<List style={{ margin: 8 }}>
{this._renderTodos()}
</List>
</div>
</MuiThemeProvider>
);
}
}
export default App;
import React,{Component}来自“React”;
从“/logo.svg”导入徽标;
导入“/App.css”;
从“物料界面/AppBar”导入AppBar;
从“物料界面/浮动操作按钮”导入浮动操作按钮;
从“材质ui/styles/MuiThemeProvider”导入MuiThemeProvider;
将*作为字符串从“/strings”导入;
从“/colors”导入*作为颜色;
从“/styles”导入样式;
从“材质ui/svg图标/content/add”导入ContentAdd;
从“物料界面/对话框”导入对话框;
从“物料界面/平面按钮”导入平面按钮;
从“react-tap事件插件”导入*作为injectTapEventPlugin;
从“物料界面/文本字段”导入文本字段;
从“物料界面/列表”导入{List,ListItem};
从“react”导入{connect};
从“/actions/index”导入{addTodo};
常量AppBarTest=()=>
;
类应用程序扩展组件{
建造师(道具){
injectTapEventPlugin();
超级(道具);
此.state={
开:错,
待办事项:[],
注:文本:“
};
this.handleChange=this.handleChange.bind(this);
}
handleOpen=()=>{
this.setState({open:true});
};
handleClose=()=>{
this.setState({open:false});
};
handleCreateNote=()=>{
让todos=[…this.state.todos];
推({
id:todos.length,
text:this.state.notetext,
已完成:false
});
this.setState({todos:todos},()=>{
//setState是异步的,所以这是回调
});
这个;
};
手变(活动){
this.setState({[event.target.name]:event.target.value});
}
_renderTodos(){
返回此.state.todos.map(事件=>{
返回(
);
});
}
_handleListItemClick(项目){
控制台日志(项目);
}
render(){
返回(
{
如果(ev.key==“输入”){
this.handleCreateNote();
ev.preventDefault();
}
}}
/>
{this.\u renderTodos()}
);
}
}
导出默认应用程序;
我想在handleCreateNote
函数中保存新的todo,我不知道如何使用store,在这里调度以将其保存在state中。有人能帮我吗?换衣服
导出默认应用程序代码>
到
您还应该使用导入所有操作
import * as actions from './action/index';
完成所有这些操作后,请按如下方式修改此函数:-
handleCreateNote = () => {
let todos = [...this.state.todos];
let newTodo = {
id: todos.length,
text: this.state.notetext,
completed: false
};
todos.push(newTodo);
this.setState({ todos: todos }, () => {
// setState is async, so this is callback
});
this.props.addTodo(this.state.notetext);
this.handleClose();
};
此外,您添加TODO的逻辑也不正确。
所以你的动作创造者应该是这样的
let taskID = 0;
export const addTodo = text => {
return {
type: "ADD_TODO",
text: text,
id: taskId++
};
};
现在减速器也需要更换,所以应该是这样的:-
const todo = (state = [], action) => {
switch (action.type) {
case "ADD_TODO":
let newTodo = {
id: action.id,
text: action.text,
status: false
};
return [...state, newTodo]
default:
return state;
}
};
export default todo;
我希望这会有帮助。不是最好的实现,但是可以解决您的问题。我可以推荐使用redux创建应用程序时几乎所有的操作都由哪个来处理。我想检查handleCreateNote中的redux状态值是什么方法?您可以这样做。props.todo来检查状态。如果我想检查完整的存储,有什么方法吗?正如我的letstore=createStore(todoApp)代码>在index.js
中,我想在另一个js文件中访问它以进行调试。这一行表示您的存储只有一个密钥常量todoApp=combineReducers({todo});如果您希望MapStateTops方法中的完整存储,只需返回完整的状态对象。正如我现在所做的返回{todo:todo},只需将其更改为返回{state:state}
const todo = (state = [], action) => {
switch (action.type) {
case "ADD_TODO":
let newTodo = {
id: action.id,
text: action.text,
status: false
};
return [...state, newTodo]
default:
return state;
}
};
export default todo;