Skip to content

Instantly share code, notes, and snippets.

@junhuif
Created September 25, 2017 10:10
Show Gist options
  • Save junhuif/a8e1b35638f526e86ad87413f4ec71b1 to your computer and use it in GitHub Desktop.
Save junhuif/a8e1b35638f526e86ad87413f4ec71b1 to your computer and use it in GitHub Desktop.
react-redux with immutable instead of pureRenderMixin demo

react-redux with immutable instead of pureRenderMixin demo

find a better way to solve the connect problem when the parent component and the child component connect different data using react-redux at the using of immutable.

A Pen by Junhui Feng on CodePen.

License.

// action type
const ADD_TODO = 'ADD_TODO'
const TOGGLE_TODO = 'TOGGLE_TODO'
const SHOW_ALL = 'SHOW_ALL'
const SHOW_ACTIVE = 'SHOW_ACTIVE'
const SHOW_COMPLETED = 'SHOW_COMPLETED'
const SET_VISIBILITY_FILTER = 'SET_VISIBILITY_FILTER'
const { createStore, combineReducers} = Redux
const { Component , addons } = React
// const { PureRenderMixin } = addons;
const {fromJS} = Immutable
const { Provider, connect } = ReactRedux
// reducers
const todo = (state, action) => {
switch (action.type) {
case ADD_TODO:
return {
id: action.id,
text: action.text,
completed: false
}
case TOGGLE_TODO:
if (state.id !== action.id) {
return state
}
return {
...state,
completed: !state.completed
}
default:
return state
}
}
const todos = (state = fromJS([]), action) => {
switch (action.type) {
case 'ADD_TODO':
return state.push(fromJS(todo(undefined, action)))
case TOGGLE_TODO:
return state.map(t => todo(t, action))
default:
return state
}
}
const visibilityFilter = (state = SHOW_ALL, action) => {
switch (action.type) {
case SET_VISIBILITY_FILTER:
return action.filter
default:
return state
}
}
const todoApp = combineReducers({
todos,
visibilityFilter
})
const FilterLink = ({filter, children}) => {
return (
<a className='link' href='#'
onClick={e => {
e.preventDefault()
store.dispatch({
type: SET_VISIBILITY_FILTER,
filter
})
}}>
{children}
</a>
)
}
let nextTodoId = 0
const ItemDesc = React.createClass ({
// mixins: [PureRenderMixin],
render() {
console.log('TodoitemDES this.props : ', this.props)
const {visibilityFilter} = this.props
return (
<span className={`${visibilityFilter} itemdes`}>
{visibilityFilter}
</span>
)
}
})
const TodoItemDESMapStateToProps = (state, props) => ({visibilityFilter: state.visibilityFilter})
const ItemDESContainer = connect(TodoItemDESMapStateToProps)(ItemDesc)
const TodoItem = React.createClass ({
// mixins: [PureRenderMixin],
render() {
console.log('Todoitem this.props : ', this.props)
let {todo} = this.props;
todo = todo.toJS();
return (
<li key={todo.id}
onClick={() => {
store.dispatch({
type: TOGGLE_TODO,
id: todo.id
})
}}
style={{
textDecoration:
todo.completed ?
'line-through' : 'none'
}}>
{todo.text}
<ItemDESContainer name='shirly'/>
</li>
)
}
})
const TodoItemMapStateToProps = (state, props) => ({...props})
// const TodoItemMapStateToProps = (state, props) => ({...props, visibilityFilter: state.visibilityFilter})
const TodoItemContainer = connect(TodoItemMapStateToProps)(TodoItem)
const TodoApp = React.createClass ({
// mixins: [PureRenderMixin],
render() {
const {todos} = this.props
return (
<div>
<input ref={node => {
this.input = node
}}/>
<button onClick={() => {
store.dispatch({
type: ADD_TODO,
text: this.input.value,
id: nextTodoId++
})
this.input.value = ''
}}>
Add Todo
</button>
<ul>
{todos.map(todo =>
<TodoItemContainer todo={todo}/>
)}
</ul>
<p>
Show:
<FilterLink filter='SHOW_ALL'>All</FilterLink>
<FilterLink filter='SHOW_ACTIVE'>Active</FilterLink>
<FilterLink filter='SHOW_COMPLETED'>Completed</FilterLink>
</p>
</div>
)
}
})
const TodoMapStateToProps = (state) => ({todos: state.todos})
const TodoContainer = connect(TodoMapStateToProps)(TodoApp)
const element = document.getElementById('root')
const store = createStore(todoApp)
const render = () => {
ReactDOM.render(
<Provider store={store}>
<TodoContainer/>
</Provider>
,
element
)
}
render()
console.log('state: ', store.getState())
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.4.4/babel.min.js"></script>
<script src="https://fb.me/react-with-addons-0.14.0.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.7/react-dom.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/redux/3.3.1/redux.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/immutable/3.7.5/immutable.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-redux/4.4.1/react-redux.min.js"></script>
.link {
margin-left: 10px;
margin-right: 10px;
}
.SHOW_COMPLETED {
color: red;
}
.SHOW_ACTIVE {
color: green;
}
.itemdes {
margin-left: 50px;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment