react-native-slider icon indicating copy to clipboard operation
react-native-slider copied to clipboard

Cannot Set Value from Parent

Open smilingkylan opened this issue 8 years ago • 4 comments

I have a "Send Transaction" scene where we want the user to drag a slider (to the left) in order to confirm that they would like to send the transaction.

Unfortunately, from what I can tell it seems that it is not possible to set the state from the parent component. Once someone slides left to confirm, the slider should move back to the right side (like a 'reset').

Here is my parent component:

<ScrollView>
         <View style={[styles.pendingSymbolArea]}>
            {this.props.sendConfirmation.pending && 
              <ActivityIndicator style={[{ flex: 1, alignSelf: 'center' }, b()]} size={'small'}/>
            }
          </View>
          <ABSlider setValue={this.setValue} onSlidingComplete={this.signBroadcastAndSave} sliderDisabled={false} onValueChange={this.onSlidingValueChange} value={this.state.sliderValue} />
        </ScrollView>
    )
  }

  onSlidingValueChange = value => {
    this.props.dispatch(updateSliderValue(value))
  }

  setValue = (val) => {
    this.setState({sliderValue: val})
  }

  signBroadcastAndSave = () => {
    // this.setState({sliderValue: 10})
    this.props.dispatch(updateSliderValue(10))
    const { transaction } = this.props
    this.props.dispatch(updateSpendPending(true))
    this.props.signBroadcastAndSave(transaction)
  }

And here is my child component:

import { Container, Content } from 'native-base'
var Slider = require('react-native-slider')

class ABSlider extends Component {
  constructor (props) {
    super(props)
    console.log('inside ABSlider, this.props is: ', this.props)
    this.state = {
      sliderDisabled: this.props.sliderDisabled,
      onSlidingComplete: this.props.onSlidingComplete,
      value: this.props.value
    }
  }

  onSlidingComplete = (value) => {
    console.log('onSlidingComplete')
    if(value <= 1) {
      this.props.onSlidingComplete()
    } else {
      this.setState({ value: 10 })
    }
  };

  onValueChange = value => {
    console.log('inside abSlider->onValueChange, value is: ', value)
    this.setState({value})
  }

  setValue = value => {
    console.log('inside abSlider->setValue, value is: ', value)    
    this.setState({value: value})    
  }

  render() {
    console.log('rendering slider, this.props is: ', this.props, ' , and this.state is: ', this.state)
    return (
      <View style={styles.container}>
        <Slider
          disabled={this.props.sliderDisabled}
          onValueChange={this.onValueChange}
          onSlidingComplete={this.onSlidingComplete}
          minimumValue={0}
          maximumValue={10}
          style={styles.slider}
          trackStyle={styles.track}
          thumbStyle={styles.thumb}
          minimumTrackTintColor='transparent'
          maximumTrackTintColor='transparent'
          thumbTouchSize={{width: 160, height: 160}}
          value={this.state.value}
        />
        <Text style={styles.textOverlay}>Slide To Confirm</Text>
      </View>
    )
  }
}

export default connect(state => ({
  
}))(ABSlider)

Any help would be appreciated. And this is just for using state... it becomes even more of an issue when I try to hook the reset into a Redux action (ASYNC success or failure of transaction send). Thanks a bunch!

smilingkylan avatar Jul 22 '17 18:07 smilingkylan

I am having a similar issue, with a different use case whereby i want to effect the value state from a different component so on and so forth.

In your case though i can think of the idea of going to node_modules/react-native-slider/src/Slider.js and editing the file to make the state.value change from 0 to 1 a certain amount of time after sliding it. Of course this would mean the slider isnt not going to be reset upon a confirmation but instead would be reset after the time allocated whether or not your use case was satisfied properly.

nuttylord avatar Jul 24 '17 08:07 nuttylord

ive been doing my own research to find my own solution and i think i came across the answer to the solution. Its simply an event dispatcher made by facebook.

https://facebook.github.io/flux/

I have yet to implement into my own project i dont know whether you need to pass the same flux dispatcher instance down through each object or if you can just declare it in each component (i think you can just declare it in both components from my experience with c# dispatchers) but its definitely a solution to your problem (and mine!).

nuttylord avatar Jul 24 '17 12:07 nuttylord

@nuttylord I am already using Redux, which is an implementation of Flux, but to no avail.

smilingkylan avatar Jul 24 '17 19:07 smilingkylan

@kylanhurt add a componentWillReceiveProps in ABSlider and there set the state again.

MaxiSantos avatar Jan 25 '18 05:01 MaxiSantos