How does Redux change UI in React?

I think the confusion you have is that part of reducer composition and selectors.

Let's look at it in a reverse order, from the UI back.

In the connected component containers/VisibleTodoList.js it gets the todos from the "state" (the global store object of redux) inside mapStateToProps, while passing it through the getVisibleTodos method.
Which can be called a selector, as it selects and returns only a portion of the data that it receives:

import { connect } from 'react-redux'
import { toggleTodo } from '../actions'
import TodoList from '../components/TodoList'

const getVisibleTodos = (todos, filter) => {
  switch (filter) {
    case 'SHOW_COMPLETED':
      return todos.filter(t => t.completed)
    case 'SHOW_ACTIVE':
      return todos.filter(t => !t.completed)
    case 'SHOW_ALL':
    default:
      return todos
  }
}

const mapStateToProps = state => {
  return {
    todos: getVisibleTodos(state.todos, state.visibilityFilter)
  }
}

const mapDispatchToProps = dispatch => {
  return {
    onTodoClick: id => {
      dispatch(toggleTodo(id))
    }
  }
}

const VisibleTodoList = connect(
  mapStateToProps,
  mapDispatchToProps
)(TodoList)

export default VisibleTodoList

The state (redux store) that passed to mapStateToProps came from the root reducer reducers/index.js and is actually a single reducer (object) that represent the combination of all other reducers via the combineReducers utility of redux:

  import { combineReducers } from 'redux'
  import todos from './todos'
  import visibilityFilter from './visibilityFilter'

  const todoApp = combineReducers({
    todos,
    visibilityFilter
  })

  export default todoApp   

As you can see, the todos reducer is there. so that's why inside the mapStateToProps we call it like this state.todos.

Here is the reducers/todos.js:

const todos = (state = [], action) => {
  switch (action.type) {
    case 'ADD_TODO':
      return [
        ...state,
        {
          id: action.id,
          text: action.text,
          completed: false
        }
      ]
    case 'TOGGLE_TODO':
      return state.map(todo =>
        (todo.id === action.id) 
          ? {...todo, completed: !todo.completed}
          : todo
      )
    default:
      return state
  }
}

export default todos  

On each action of type 'ADD_TODO' it will return a new state with the new todo:

case 'ADD_TODO':
          return [
            ...state,
            {
              id: action.id,
              text: action.text,
              completed: false
            }
          ]  

This the the action creator for it inside actions/index.js:

let nextTodoId = 0
export const addTodo = text => {
  return {
    type: 'ADD_TODO',
    id: nextTodoId++,
    text
  }
}

So here is the full flow of redux (i omitted the button that calls the action as i assume this is obvious part for you).
Well, almost a full flow, none of this could have happened without the Provider HOC that wraps the App and inject the store to it in index.js:

import React from 'react'
import { render } from 'react-dom'
import { Provider } from 'react-redux'
import { createStore } from 'redux'
import todoApp from './reducers'
import App from './components/App'

let store = createStore(todoApp)

render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById('root')
)

Now when the redux state changes, a call to mapStateToProps is invoked that will return the new mapped props. connect will pass those new props and this will trigger a new render call (actually the entire react life cycle flow) to the connected component.
This way the UI will be re-rendered with the fresh new data from the store.