Reputation: 883
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
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