减速器从哪里获得状态?

时间:2019-11-17 06:26:20

标签: reactjs redux react-redux

我试图借助在线待办事项应用程序资源来了解redux。 但是,我似乎无法弄清楚“ todos”减速器从何处获得初始状态? 我已经控制了该状态,但似乎无法将其包裹住吗? 初始渲染后,状态被控制为3倍,

  1. []
  2. []
  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  ----------

2 个答案:

答案 0 :(得分:0)

您正在此处定义初始状态:

function todos(state = [], action) {

通常,在定义化简器时,我们还定义initialStatestate = [] 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:),在这里减速器获得此初始状态