我试图借助在线待办事项应用程序资源来了解redux。 但是,我似乎无法弄清楚“ todos”减速器从何处获得初始状态? 我已经控制了该状态,但似乎无法将其包裹住吗? 初始渲染后,状态被控制为3倍,
链接:“ https://codepen.io/iamrkcheers/pen/rNNoBvB”
感谢您的帮助。
谢谢。
// --------- actions start ----------
const ADD_TODO = "ADD_TODO";
const TOGGLE_TODO = "TOGGLE_TODO";
const SET_VISIBILITY_FILTER = "SET_VISIBILITY_FILTER";
const VisibilityFilters = {
SHOW_ALL: "SHOW_ALL",
SHOW_COMPLETED: "SHOW_COMPLETED",
SHOW_ACTIVE: "SHOW_ACTIVE"
};
let nextTodoId = 3;
function addTodo(text) {
return {
type: ADD_TODO,
id: nextTodoId++,
text
}
}
function toggleTodo(id) {
return {
type: TOGGLE_TODO,
id
}
}
function setVisibilityFilter(filter) {
return {
type: SET_VISIBILITY_FILTER,
filter
}
}
// --------- actions end ----------
// --------- reducers start ----------
function todos(state = [], action) {
console.log('state is:',state);
switch (action.type) {
case ADD_TODO: {
return [...state, {
text: action.text,
completed: false,
id: action.id
}];
}
case TOGGLE_TODO: {
return state.map((todo, id) => {
if (id === action.id) {
return Object.assign({}, todo, {
completed: !todo.completed
});
}
return todo;
});
}
default: {
return state;
}
}
}
function visibilityFilter(state = VisibilityFilters.SHOW_ALL, action) {
switch (action.type) {
case SET_VISIBILITY_FILTER: {
return action.filter;
}
default: {
return state
}
}
}
const todoApp = Redux.combineReducers({
visibilityFilter,
todos
});
// --------- reducers end ----------
// --------- components start ----------
const App = () => {
const getDate = date => new Date(date);
const days = ["Воскресенье", "Понедельник", "Вторник", "Среда", "Четверг", "Пятница", "Суббота"];
return (
<div className="block">
<div className="info-date">
<div className="date">{ getDate(Date.now()).toLocaleDateString("ru") }</div>
<div className="day">{ days[getDate(Date.now()).getDay()] }</div>
</div>
<AddTodo />
<Footer />
<VisibleTodoList />
</div>
);
};
const Footer = () => {
return (
<div className="filters">
<FilterLink filter="SHOW_ALL">Все задачи</FilterLink>
<FilterLink filter="SHOW_ACTIVE">Активные</FilterLink>
<FilterLink filter="SHOW_COMPLETED">Завершенные</FilterLink>
</div>
);
};
const Link = ({ active, children, onClick }) => {
if (active) {
return <span className="filter-item non-active">{ children }</span>
}
return (
<a className="filter-item" href="#" onClick = { event => {
event.preventDefault();
onClick();
} }>{ children }</a>
);
};
const Todo = ({ onClick, completed, text }) => {
const styles = {
textDecoration: completed ? "line-through" : "none"
};
return (
<li onClick = { onClick } style = { styles }>
<a>{ text }</a>
</li>
);
};
const TodoList = ({ todos, onTodoClick }) => {
return (
<div className="list">
<ul>
{
todos.map(todo => <Todo
key = { todo.id } { ...todo }
onClick = { () => onTodoClick(todo.id) } />)
}
</ul>
</div>
);
};
// --------- components end ----------
// --------- containers start ----------
let AddTodo = ({ dispatch }) => {
let input;
return (
<div>
<form className="addForm" onSubmit = { event => {
event.preventDefault();
if (!input.value.trim()) {
return;
}
dispatch(addTodo(input.value));
input.value = "";
} }>
<input type="text" placeholder="Что нужно сделать?" ref = { node => input = node }/>
<button type="submit" className="btn"></button>
</form>
</div>
);
};
AddTodo = ReactRedux.connect()(AddTodo);
var mapStateToProps = (state, ownProps) => {
return {
active: ownProps.filter === state.visibilityFilter
};
};
var mapDispatchToProps = (dispatch, ownProps) => {
return {
onClick: () => {
dispatch(setVisibilityFilter(ownProps.filter));
}
};
};
const FilterLink = ReactRedux.connect(
mapStateToProps,
mapDispatchToProps
)(Link);
const getVisibleTodos = (todos, filter) => {
switch (filter) {
case "SHOW_ALL": {
return todos;
}
case "SHOW_COMPLETED": {
return todos.filter(todo => todo.completed);
}
case "SHOW_ACTIVE": {
return todos.filter(todo => !todo.completed);
}
default: {
return todos;
}
}
};
var mapStateToProps = state => {
return {
todos: getVisibleTodos(state.todos, state.visibilityFilter)
}
};
var mapDispatchToProps = dispatch => {
return {
onTodoClick: id => {
dispatch(toggleTodo(id));
}
};
};
const VisibleTodoList = ReactRedux.connect(
mapStateToProps,
mapDispatchToProps
)(TodoList);
// --------- containers end ----------
// --------- application start ----------
const initialState = {
visibilityFilter: "SHOW_ALL",
todos: [
{
id: 0,
text: "Изучить React",
completed: true
},
{
id: 1,
text: "Изучить Redux",
completed: true
},
{
id: 2,
text: "Написать приложение \"Список задач\"",
completed: false
}
]
};
let store = Redux.createStore(todoApp, initialState);
ReactDOM.render(
<ReactRedux.Provider store = { store }>
<App />
</ReactRedux.Provider>,
document.querySelector("#root")
);
// --------- application end ----------
答案 0 :(得分:0)
您正在此处定义初始状态:
function todos(state = [], action) {
通常,在定义化简器时,我们还定义initialState
(state = [] in your case
),这是进入化简器的状态,直到我们用数据填充(从api或user等外部源)输入)。
您可以在此处了解更多有关初始状态的信息:https://redux.js.org/recipes/structuring-reducers/initializing-state#initializing-state
答案 1 :(得分:0)
有两种方法可以定义初始状态;
第一个是在减速器中您执行过的功能
func application(_: configurationForConnecting:, options:)
和,
第二个是创建商店时,可以在createStore函数中将初始状态作为第二个参数传递。在您的情况下,创建商店时会有第二个参数,它是由三个待办事项组成的数组,在控制台登录时可以看到。 func application(_:, didDiscardSceneSessions:)
,在这里减速器获得此初始状态