2017-03-02 12 views
2

スイッチコンポーネントが内部にあります。この全体のコンポーネントはクリック可能です。このコンポーネントをクリックすると、dispatch(reduxストアを変更する)が実行され、このコンポーネントが再レンダリングされます。 私が必要とするのは、コンポーネント全体を再レンダリングせず、そのスイッチコンポーネントを適切な状態にアニメーション化することです。このReact Native(Redux付き)animateプログラム的にスイッチ

<TouchableOpacity onPress={onPress}> 
    <Text>{this.props.title}</Text> 
    <Switch value={this.state.active}/> 
</TouchableOpacity> 

任意のアイデアのような

何か?

私はこの非常に一般的な使用例を見つけました。私はこのようなシナリオがたくさんあるので、私はこの動作が必要ですが、ウェブ上で例や解決策を見つけることはできません。たぶん私は何かが欠けているかもしれません。私もこれを試してみました

おかげ

--- EDIT ---

。私はshouldComponentUpdateで更新を無効にしようとしましたが、私はwillRecievePropsでのみ状態を設定しようとしました、そして/またはトグルしなくてもトグルしました。私もLayoutAnimationで試してみました。しかし、何も動作しません。 this.setState()は、Switchコンポーネントをアニメーション化しません。 また、this._switch._rctSwitch.setNativeProps({value:nextProps.active})で再生しようとしましたが、これは動作しません(また、_rctSwitchのために匂いがします)。

class ViewWithSwitchInside extends React.Component { 
    constructor(props) { 
     super(props) 
     this.toggle = this.toggle.bind(this); 
     this.state = { 
      active: props.active 
     } 
    } 

    componentWillReceiveProps(nextProps) { 
     if (this.state.active != nextProps.active) { 
      this.setState({ active: nextProps.active }) 
     } 
    } 

    toggle() { 
     let newValue = !this.state.active 
     this.setState({ 
      active: newValue, 
     }) 
     if (typeof this.props.onClick === 'function') { 
      this.props.onClick(newValue) 
     } 
    } 

    render() { 
     return (
      <TouchableWithoutFeedback onPress={this.toggle}> 
       <View> 
        <Text>{this.props.title}</Text> 
        <Switch value={this.state.active} /> 
       </View> 
      </TouchableWithoutFeedback> 
     ) 
    } 
} 
+0

代わりにこのようなことをしてもらえますか? http://stackoverflow.com/questions/40865391/how-to-show-text-yes-no-inside-a-switch-in-react-native – Tom

+0

私はあなたが何を指しているのかわからないアニメーションで。でも、私は元の質問を編集しました。これは最小の例ですが、試してみてください。アニメーション化されません。変更は、そのスイッチを直接クリックした場合にのみアニメーション表示されます。これがバグかどうかはわかりませんが、基本的な機能のようです。 – trubi

+0

@trubi:私は同じ問題を抱えているかもしれませんが、あなたの問題を正確に理解できません。私はあなたがそれをクリックするとアニメートするスイッチを持っていますが、私はまた、他のユーザーのやりとりに基づいてそれを切り替える必要があります。しかし、単に 'setState'でそれを変更すると、スムーズなアニメーションなしに他の位置に即座にジャンプします。これはあなたの問題とは違いますか? – hippietrail

答えて

0

親コンポーネントから子を1つだけレンダリングすることはできません。スイッチが依存する変数の値を何らかの形で変更することができたとしても、親コンポーネントを再レンダリングしない限り表示されません。

私はスイッチャーの値を設定するために、グローバル変数を使用しようと、私はまた、あなたがhere

これは私の結果であるの詳細を読むことができますshouldComponentUpdate()を使用して親コンポーネントの再レンダリングを防止しました

これは私のアプリの初期状態です。そのグローバル変数はfalseに設定され、親コンポーネントは既にレンダリングされています。

enter image description here

今、私はSwitch周りViewをタップしてtrueにグローバル変数を変更し、それが

enter image description here

は変わりますが、何も視覚的に変化していない、唯一の変数はスイッチャー、ない変更。

Iは、画面の下部にある「再レンダリング」テキストを押してstateSwitch成分とは無関係の変化)を変更し、これが起こる:

Result of re-rendering

これはコードであります

var isActive = false; //global variable 
class Test extends Component { 
    constructor(props) { 
    super(props); 
    this.state={active:false, irrelevantState: true}; 
    } 

    test(foo){ 
    console.log("Attempting to change", foo); 
    isActive = foo; 
    } 

    shouldComponentUpdate(nextProps, nextState){ 
    if(this.state.active != nextState.active){//If the new state is different than the previous, stop rendering. 
     this.test(nextState.active); 
     return false; 
    }else { //else, re-render everything 
     return true; 
    } 
    } 

    render(){ 
    console.log("Test re-render"); 
    return(
     <View style={{flex:1}}> 
     <TouchableOpacity onPress={()=>{this.setState({active:!this.state.active})}} style={{flex:1, marginTop:20}}> 
      <Text>Test Component</Text> 
      <Switch value={isActive}/> 
     </TouchableOpacity> 
     <TouchableOpacity onPress={()=>{this.setState({active:true})}} style={{flex:1, marginTop:20}}> 
      <Text>Test Component</Text> 
      <Switch value={isActive}/> 
     </TouchableOpacity> 
     <TouchableOpacity style={{height:20}} onPress={()=>this.setState({irrelevantState:false})}> 
      <Text> Re-render</Text> 
     </TouchableOpacity> 
     </View> 
    ) 
    } 
} 

あなたの最善の策無視して、あなたのアプリケーションは、変更を機能させるためだけthis.state.activeおよびその他の必要な状態を再レンダリングするスマートな方法を見つけることです:アプリケーション上では、のその他の変更。

+0

これが必要なすべてのコンポーネントのグローバル変数は1つ狂っています。子コンポーネントを1つだけ再レンダリングする必要はありません。コンポーネント全体が再レンダリングされる可能性があります。私が必要とするのは、そのスイッチをアニメーションでレンダリングすることだけです。または、レンダリングしないようにすると、そのスイッチでisOn()を設定するだけです。これがネイティブiOSスイッチの仕組みです。このメソッドを呼び出すと、それ自体がアニメーション化されます。 setNativeProps()はどうですか?自分自身のネイティブスイッチラッパーを実装する必要がありますか? – trubi

関連する問題