Reduxとreact-reduxでReact Nativeをテストしたところ、Redux のステート ツリーの内容がコンテナを介して渡されない場合、表示に反映されないことがわかりました。
これをテストするために私は使用します
- 反応ネイティブ 0.19.0
- 反応還元 4.1.2
- 還元3.1.7
@alinzin がhttps://github.com/alinz/example-react-native-reduxでこのプロジェクトをセットアップするためのすべてのトリックを説明しているように。他に良い解決策はありますか?
次の例は、Redux ストアの状態としての単純な文字列と、文字列を拡大するための単純なアクションを示しています。
これは、状態の単一の文字列としてのreduceとdataです。
//Reducer
const reducer = (state = { data: '[][][]' }, action = {}) => {
switch (action.type) {
case ENLARGE:
return Object.assign({}, state, {
data: state.data+'[]'
})
default:
return state
}
}
登録したアプリはこんな感じで目新しいものはありません。最初のルートは、App1Component のコンテナーを起動します。これが良好なバインディング状態とコンポーネントへの道です (私は信じています)
export default class App extends Component {
render () {
return (
<Provider store={store}>
<Navigator style={{flex: 1}}
initialRoute={{
component: Container,
}}
renderScene={ (route, navigator) => {
const Component = route.component;
return (
<View style={{flex: 1, marginTop:40}}>
<Component navigator={navigator} route={route} {...route.passProps} />
</View>
);
}}
/>
</Provider>
)
}
}
コンポーネント App1Component と App2Componenet の両方のメイン コンテンツは単純なコンポーネントであり、文字列を表示するだけで、拡大アクションをディスパッチするための「ボタン」を表示します。
class MainContent extends Component{
render() {
return (
<View>
<Text>{this.props.data}-{this.props.data.length}</Text>
<TouchableOpacity onPress={()=>{this.props.enlarge()}} >
<Text>Click to Enlarge me!</Text>
</TouchableOpacity>
<Text> </Text>
</View>
)
}
}
コンポーネント App1 と App2 の間に違いはありません。App1Component だけが Container (およびバインド状態とアクション) を介して呼び出され、App2Component は (App1Component から) Navigator ですべて同じ props (App1Component と同じ) をプッシュすることによって呼び出されます。
次のシーンを App2Component にプッシュし、コンテナを介してバインドされる前に同じ小道具を渡すためのボタンを備えた App1Component があります。
class App1Component extends Component {
render() {
return (
<View>
<MainContent {...this.props}/>
<TouchableOpacity onPress={()=>{
this.props.navigator.push({
name: 'App2',
component: App2Component,
passProps: {...this.props}
})
}}>
<Text>Click to Forward to App2Component {'\n'}passing props through Navigator passProps</Text>
</TouchableOpacity>
</View>
)
}
}
ここで「拡大」を押すと文字列が拡大され、画面にアクションが反映されているのがわかります。また、redux logger のトレースを chrome で見ることができます。
App1Component のラッパー コンテナ
const Container = connect(
(state) => ({
data: state.data
}),
(dispatch) => ({
enlarge: () => dispatch(enlarge())
})
)(App1Component)
そして、ここにコンポーネント 2、戻るボタンがあります。ここで「拡大」を押すと文字列が拡大され、確かにchrome上でトレースが確認できるのですが……画面にアクションが反映されていません。
class App2Component extends Component {
render() {
return (
<View>
<MainContent {...this.props}/>
<TouchableOpacity onPress={()=>{this.props.navigator.pop()}} >
<Text>Back to App1Component{'\n'}to see the change!</Text>
</TouchableOpacity>
</View>
)
}
}
[戻る] を押すと、App1Component の変更された文字列が画面に表示されます。
ご覧のとおり、私は何か根本的なことを誤解していましたが、本質的なことではありません。
すべてのメイン コンポーネント (ページ/シーン) をコンテナーで装飾する必要がありますか? Navigator で passPros を介して props (以前はコンテナにバインドされていた) を渡すのが間違っているのはなぜですか? アクションは正しくディスパッチされますが、画面には反映されません。
どんな助けでも大歓迎です。ありがとう