这是 http://cn.redux.js.org/docs/basics/ExampleTodoList.html(
2.6 示例: Todo 列表
// actions.js
/*
* action 类型
*/
export const ADD_TODO = 'ADD_TODO';
export const COMPLETE_TODO = 'COMPLETE_TODO';
export const SET_VISIBILITY_FILTER = 'SET_VISIBILITY_FILTER'
/*
* 其它的常量
*/
export const VisibilityFilters = {
SHOW_ALL: 'SHOW_ALL',
SHOW_COMPLETED: 'SHOW_COMPLETED',
SHOW_ACTIVE: 'SHOW_ACTIVE'
};
/*
* action 创建函数
*/
export function addTodo(text) {
return { type: ADD_TODO, text }
}
export function completeTodo(index) {
return { type: COMPLETE_TODO, index }
}
export function setVisibilityFilter(filter) {
return { type: SET_VISIBILITY_FILTER, filter }
}
// reducers.js
import { combineReducers } from 'redux'
import { ADD_TODO, COMPLETE_TODO, SET_VISIBILITY_FILTER, VisibilityFilters } from './actions'
const { SHOW_ALL } = VisibilityFilters
function visibilityFilter(state = SHOW_ALL, action) {
switch (action.type) {
case SET_VISIBILITY_FILTER:
return action.filter
default:
return state
}
}
function todos(state = [], action) {
switch (action.type) {
case ADD_TODO:
return [
...state,
{
text: action.text,
completed: false
}
]
case COMPLETE_TODO:
return [
...state.slice(0, action.index),
Object.assign({}, state[action.index], {
completed: true
}),
...state.slice(action.index + 1)
]
default:
return state
}
}
const todoApp = combineReducers({
visibilityFilter,
todos
})
export default todoApp
// App.js
import React, { Component, PropTypes } from 'react'
import { connect } from 'react-redux'
import { addTodo, completeTodo, setVisibilityFilter, VisibilityFilters } from '../actions'
import {
View,Text,TextInput,TouchableHighlight,Alert
} from 'react-native';
export class Todo extends Component {
render() {
return (
<Text
style={{
color:this.props.completed ?'red':'black',
}}
onPress={this.props.onClick}>
{this.props.text}
</Text>
)
}
}
Todo.propTypes = {
onClick: PropTypes.func.isRequired,
text: PropTypes.string.isRequired,
completed: PropTypes.bool.isRequired
}
export class TodoList extends Component {
constructor(props) {
super(props);
}
render() {
return (
<View>
{this.props.todos.map((todo, index) =>
<Todo {...todo}
key={index}
onClick={() => this.props.onTodoClick(index)} />
)}
</View>
)
}
}
TodoList.propTypes = {
onTodoClick: PropTypes.func.isRequired,
todos: PropTypes.arrayOf(PropTypes.shape({
text: PropTypes.string.isRequired,
completed: PropTypes.bool.isRequired
}).isRequired).isRequired
}
export class AddTodo extends Component {
constructor(props) {
super(props);
this.state = {
text: '',
};
}
render() {
return (
<View>
<TextInput ref='input'
onChangeText={(text) => this.setState({text})}
value={this.state.text} />
<Text onPress={this.handleClick.bind(this)}>Add</Text>
</View>
)
}
handleClick() {
//const node = this.refs.input;
//const text = node.value.trim()
const text = this.state.text.trim();
/*this.props.onAddClick(text)
node.value = ''*/
this.props.onAddClick(text);
this.setState({text:''});
}
}
AddTodo.propTypes = {
onAddClick: PropTypes.func.isRequired
}
export class Footer extends Component {
renderFilter(filter, name) {
if (filter === this.props.filter) {
return name
}
return (
<Text onPress={e => {
this.props.onFilterChange(filter)
}}>
{name}
</Text>
)
}
render() {
return (
<Text>
Show:
{' '}
{this.renderFilter('SHOW_ALL', 'All')}
{', '}
{this.renderFilter('SHOW_COMPLETED', 'Completed')}
{', '}
{this.renderFilter('SHOW_ACTIVE', 'Active')}
.
</Text>
)
}
}
Footer.propTypes = {
onFilterChange: PropTypes.func.isRequired,
filter: PropTypes.oneOf([
'SHOW_ALL',
'SHOW_COMPLETED',
'SHOW_ACTIVE'
]).isRequired
}
class App extends Component {
constructor(props) {
super(props);
}
render() {
const { dispatch, visibleTodos, visibilityFilter } = this.props
return (
<View style={{
flex: 1,
backgroundColor: 'white',
}}>
<AddTodo
onAddClick={text =>
dispatch(addTodo(text))
} />
<TodoList
todos={visibleTodos}
onTodoClick={index =>
dispatch(completeTodo(index))
} />
<Footer
filter={visibilityFilter}
onFilterChange={nextFilter =>
dispatch(setVisibilityFilter(nextFilter))
} />
</View>
)
}
}
App.propTypes = {
visibleTodos: PropTypes.arrayOf(PropTypes.shape({
text: PropTypes.string.isRequired,
completed: PropTypes.bool.isRequired
}).isRequired).isRequired,
visibilityFilter: PropTypes.oneOf([
'SHOW_ALL',
'SHOW_COMPLETED',
'SHOW_ACTIVE'
]).isRequired
}
function selectTodos(todos, filter) {
switch (filter) {
case VisibilityFilters.SHOW_ALL:
return todos
case VisibilityFilters.SHOW_COMPLETED:
return todos.filter(todo => todo.completed)
case VisibilityFilters.SHOW_ACTIVE:
return todos.filter(todo => !todo.completed)
}
}
// Which props do we want to inject, given the global state?
// Note: use https://github.com/faassen/reselect for better performance.
function select(state) {
return {
visibleTodos: selectTodos(state.todos, state.visibilityFilter),
visibilityFilter: state.visibilityFilter
}
}
// 包装 component ,注入 dispatch 和 state 到其默认的 connect(select)(App) 中;
export default connect(select)(App)//export default App;index.android.js
import React, { Component } from 'react';
import {
AppRegistry,
Alert,
Image,
StyleSheet,
Text,
TouchableHighlight,
TouchableOpacity,
View,
ViewPagerAndroid,
} from 'react-native';
import { createStore } from 'redux';
import { Provider } from 'react-redux';
import todoApp from './reducers';
import App from './containers/App';
var alertMessage = 'Credibly reintermediate next-generation potentialities after goal-oriented ' +
'catalysts for change. Dynamically revolutionize.';
var store = createStore(todoApp);
class AwesomeProject extends Component {
render() {
return(
<Provider store={store}><App></App></Provider>
);
}
}
var styles = StyleSheet.create({
wrapper: {
borderRadius: 5,
marginBottom: 5,
},
button: {
backgroundColor: '#eeeeee',
padding: 10,
},
});
AppRegistry.registerComponent('AwesomeProject', () => AwesomeProject);
//index.android.js
import React, { Component } from 'react';
import {
AppRegistry,
Alert,
Image,
StyleSheet,
Text,
TouchableHighlight,
TouchableOpacity,
View,
ViewPagerAndroid,
} from 'react-native';
import { createStore } from 'redux';
import { Provider } from 'react-redux';
import todoApp from './reducers';
import App from './containers/App';
var alertMessage = 'Credibly reintermediate next-generation potentialities after goal-oriented ' +
'catalysts for change. Dynamically revolutionize.';
var store = createStore(todoApp);
class AwesomeProject extends Component {
render() {
return(
<Provider store={store}><App></App></Provider>
);
}
}
var styles = StyleSheet.create({
wrapper: {
borderRadius: 5,
marginBottom: 5,
},
button: {
backgroundColor: '#eeeeee',
padding: 10,
},
});
AppRegistry.registerComponent('AwesomeProject', () => AwesomeProject);