sajid
sajid

Reputation: 883

How to reset react native Slider (child component) after I render the parent component?

I am quite new to React/React-Native. I am building a small app which renders a heat-map by using data from an API server. I have a date picker that filters the data set that I fetch and so controls the rendered heat map. After I fetch and render the heatmap then the user can slide over the data set and see the corresponding results. So the max and mean value of the slider is dictated by the date picker. I set the state every time date picker picks a new date and render the HeatMap component with the new state (which is the parent component which includes the slider component). After I render I want my Slider to move the starting position (value=0). However the slider seems to be in the same position as the previous state. How can I achieve the desired behavior.

Here is my parent component which includes the date picker and the Slider component.

   class Home extends Component {
      constructor(props) {
        let start_date = new Date();
        start_date.setDate(1);
        start_date.setMonth(0);
        start_date.setFullYear(2019);
        let date = getLastBusinessDay(start_date);
        super(props);
        this.state = {
          date: date,
          data: false,
          slider: getGermanFormatDate(date)
        };
      }

  componentWillMount() {
    this.getHeatData();
  }

  getHeatData = () => {
    axios
      .get(heat_data_url, {
        params: {
          date: getGermanFormatDate(this.state.date)
        }
      })
      .then(response => this.setState({ data: response.data }));
  };

  setDate = date => {
    this.setState({ date: date }, this.getHeatData);
    this.setState({ slider: getGermanFormatDate(date) });
  };

  onSlideCallBack = value => {
    this.setState({ slider: value });
    this.setState({ date: makeDateFromString(value) });
  };

  render() {
    if (!this.state.data) {
      return (
        <View style={styles.activityIndicator}>
          <ActivityIndicator size="large" color="#0000ff" />
        </View>
      );
    } else {
      return (
        <View style={styles.main}>
          {/* // Header Menu bar */}
          <View>
            <HeaderComponent
              navigation={this.props.navigation}
              title="Global Risk Alert"
            />
          </View>
          {/* // Headr Menu bar ends */}

          {/* // Main Content section */}
          <View style={styles.content}>
            {/* // Header content */}
            <View
              style={{
                flex: 0,
                height: 50
              }}
            >
              <Text style={styles.headerText}>Global Risk Dynamic</Text>
            </View>
            {/* // Header content ends */}

            {/* Heatmap section */}
            <Heatmap heat_data={this.state.data} date={this.state.date} />
            {/* Heatmap section ends */}
            <View>
              <Text style={styles.headerText}>{this.state.slider}</Text>
            </View>
            {/* Slider section */}
            <DateSlider
              callBack={this.onSlideCallBack}
              data={this.state.data}
            />
            {/* Slider section  ends */}

            {/* DatePicker section */}
            <PickDate
              callBack={this.setDate}
              slider_date={this.state.slider}
              navigation={this.props.navigation}
              data={this.state.data}
            />
            {/* DatePicker section  ends */}
          </View>
          {/* // Main Content section ends */}

          <View>
            <SocialMedia />
          </View>
        </View>
      );
    }
  }
}

And here is my Slider component

const DateSlider = props => {
    const runCallBack = value => {
    let dates = Object.keys(props.data);
    dates = dates.map(_getDate);

    // dates are of the format ["22.7.2019", "23.7.2019"]
    dates.sort((a, b) => a - b);
    dates = dates.map(getGermanFormatDate);
    props.callBack(dates[value]);
  };
   const _getDate = date_string => {
   // date_string is of the format 22.7.2019
    let date = new Date();
    date.setDate(date_string.split(".")[0]);
    date.setMonth(date_string.split(".")[1] - 1);
    date.setFullYear(date_string.split(".")[2]);
    return date;
  };

  if (getDataLength(props.data) <= 1) {
    return <View />;
  }
  return (
     <View style={styles.container}>
       <Slider
         value={0}
         onValueChange={runCallBack}
         minimumValue={0}
         maximumValue={getDataLength(props.data)}
         step={1}
       />
      </View>
   );
 };

UPDTE: When should the slider be brought back to the starting end (reset): Whenever I pick a new a date from the date picker. The date picker event calls the 'setDate' method (in the parent component), which sets the 'date' state and calls the 'getHeatData' method. Get heatData fetches the data and sets the 'data' state. The 'data' state dictates the 'maximumValue' of the of the slider. So basically I want to reset (bring the slider pointer back the to starting end) the Slider whenever I choose a new date.

Upvotes: 0

Views: 928

Answers (1)

remeus
remeus

Reputation: 2449

If you want your slider value to reset on specific actions, one possible solution is to control its value from the parent component.

You already have this value store in your parent's state, so you can just pass it to the child:

<DateSlider
  callBack={this.onSlideCallBack}
  data={this.state.data}
  sliderValue={this.state.slider}
/>

Then in your child component, you use this value for the slider:

<Slider
  value={this.props.sliderValue}
  onValueChange={runCallBack}
  minimumValue={0}
  maximumValue={getDataLength(props.data)}
  step={1}
/>

And now you can just update slider in your parent whenever you want and it will re-render the slider. Actually you are already doing this in setDate so the slider will re-render on date picking.

Upvotes: 1

Related Questions