how to set initial state in redux

It needs to be the second argument to createStore:

const rootReducer = combineReducers({
  todos: todos,
  visibilityFilter: visibilityFilter
});

const initialState = { 
  todos: [{id:123, text:'hello', completed: false}] 
};

const store = createStore(
  rootReducer, 
  initialState
);

You can set the initial state in the reducer(s).

const initialTodos = [{id:123, text:'hello', completed: false}]

// this is the ES2015 syntax for setting a default value for state in the function parameters
function todoReducer(state = initialTodos, action) {
  switch(action.type) {
    ... 
  }
  return state
}


const todoApp = combineReducers({
  // todos now defaults to the array of todos that you wanted and will be updated when you pass a new set of todos to the todoReducer
  todos: todoReducer,
  visibilityFilter
})

There have been great answers so far but let me ice the cake; perhaps to give you an in-depth analysis, so that you don't just copy StackOverflow codes``` that works but don't know why your program is working.

There are two main ways to accomplish this viz: 1. using the createStore method. It takes an optional second argument (the preloadedState value)

const store = createStore(counter) // createStore without preloadedState
const initialState = {} // or in your case:
const initialState = {
                         initialTodos = [{id:123, text:'hello', completed: false}]
                     }
const store = createStore(counter, initialState) // create store with preloadedState

if you call createStore without the preloadedState it would initialize the state to {} Hence the reducers will receive undefined as their state values. That brings us to the second method.

  1. You can set it at the reducers. Reducers can also set initialState by looking at the incoming state argument (which would be undefined if createStore is not called with initialState) and returning the values they would like to use as default.
const initialState = {} // a common pattern but in your case:
const initialState = {
                         initialTodos = [{id:123, text:'hello', completed: false}]
                     }
function todoReducer(state = initialState, action) {
  switch (action.type) {
    case // your type:
      return ...
    default:
      return state
  }
}

The drawback of method 2 is evident in a case where there is huge data; like a huge todo list for instance that you want to pass as initialState "app-wide". Method 2 would bring in a lot of repetition as you would have to do the same thing across all your reducers. This is the main drawback. But it is quite popular when you just want to set initialState as {} it is a common pattern.

Here is a 4min read for better understanding: https://dev.to/lawrence_eagles/how-to-properly-set-initial-state-in-redux-78m