React-instantsearch: How to get auto computed Min and Max for connectRange

Created on 21 Jan 2018  路  5Comments  路  Source: algolia/react-instantsearch

Hi,

I'm working on a RangeSlider component and would like to know how to get the auto computed Min and Max values as mentioned in the docs.

name | type | description
---|---|---
min | type:聽number | 聽Minimum value. When this isn鈥檛 set, the minimum value will be automatically computed by Algolia using the data in the index.
max | type:聽number | 聽Maximum value. When this isn鈥檛 set, the maximum value will be automatically computed by Algolia using the data in the index.

I've tried currentRefinement but that shows undefined until you actually start moving the slider, then it has the proper min and max. Also this doesn't seem correct as it will change as a refinement is applied.

Thanks,

API

All 5 comments

Hi, thanks for ask about this because it's missing in the documentation. Those values are computed automatically from the Algolia results when the min or max are not given to the connector. Then they will be provided to the connected component as min & max.

Take the following example:

const Range = connectRange(({ min, max, currentRefinement }) => null);

<Range /> // will compute both `min` & `max` from the Algolia results

<Range min={10} /> // will compute only `max` since `min` is provided

@samouss so I if follow the above example, the min and max are undefined when the component first mounts. They get updated to the proper values when I move the slider, but I need the values when the component mounts so that I can set the min/max range on the slider, otherwise the slider doesn't work. Any way around this?

My code:

export const DrawerRangeMultiSlider = connectRange(({refine, currentRefinement, header, min, max}) => {
  return(
    <RangeMultiSlider refine={refine} currentRefinement={currentRefinement} header={header} min={min} max={max}/>
  )
})

export class RangeMultiSlider extends React.Component{
  constructor(props){
    super(props);
    console.log('this.props', this.props)
    this.state = {
      sliderValues: [this.props.min, this.props.max]
    };
  }

  onChangeValues = (values) => {
    console.log('Slider values', values)
    console.log('this.props', this.props)
    this.setState({
      sliderValues: [values[0], values[1]]
    });
  }

  onChangeValuesFinish() {
    if (this.props.currentRefinement.min !== this.state.sliderValues[0] || this.props.currentRefinement.max !== this.state.sliderValues[1]) {
      this.props.refine({min: this.state.sliderValues[0], max: this.state.sliderValues[1]});
    }    
  }

  render(){
    return(
    <View style={{padding:8}}>
      <Text style={{paddingLeft: 10, fontSize: 14, color: Colors.primaryTextColor, alignSelf: 'flex-start' , textAlign: 'left'}}>
        {`${this.props.header}:`}
      </Text>
      <View style={{paddingTop: 20, paddingLeft: 8}}>
        <MultiSlider
          sliderLength={150}
          selectedStyle={{backgroundColor: Colors.mainColor}}
          unselectedStyle={{backgroundColor: 'silver'}}
          containerStyle={{height:10}}
          touchDimensions={{
              height: 40,
              width: 40,
              borderRadius: 20,
              slipDisplacement: 40,
          }}
          onValuesChange={(sliderState) => this.onChangeValues(sliderState)}
          min={this.props.min}
          max={this.props.max}
          onValuesChangeFinish={() => this.onChangeValuesFinish()}
          values={[this.state.sliderValues[0], this.state.sliderValues[1]]}
          step={1}
          customMarker={SliderMarker}/>
      </View>
      <View style={{flexDirection: 'row', justifyContent: 'space-between'}}>
        <Text style={{fontSize: 14, color: Colors.primaryTextColor, textAlign: 'left'}}>
          {this.state.sliderValues[0]}
        </Text>
        <Text style={{fontSize: 14, color: Colors.primaryTextColor , textAlign: 'right'}}>
          {this.state.sliderValues[1]}
        </Text>
      </View>
    </View>
    )
  }
}

Calling it like this inside a drawer:

                                    <DrawerRangeMultiSlider
                                        header={'Price'}
                                        attributeName={'price'}
                                        precision={2}/>

Yes it's normal that on the first render those values are undefined. The query to Algolia is not fulfilled yet, so the values are not initialised. They will be updated on a later render. But in your case the min & max on the slider will be correctly updated but the state of the component is not, until the user update the slider. What you need is to update the state when the component will receive new props. We have an example on Storybook that show an integration of a slider with the connectRange connector. You can find the source code on Github. The interesting part is located in componentWillReceiveProps.

https://github.com/algolia/react-instantsearch/blob/6999decaef4a2e58a779489b6342645e0e7aa086/stories/3rdPartyIntegrations.stories.js#L27-L36

Ok got it, I will use componentWillReceiveProps.

Thanks!

I'll close the issue, feel free to reopen it if needed 馃槈

Was this page helpful?
0 / 5 - 0 ratings

Related issues

developerk786 picture developerk786  路  3Comments

itsmichaeldiego picture itsmichaeldiego  路  4Comments

noclat picture noclat  路  3Comments

aaronbushnell picture aaronbushnell  路  4Comments

danhodkinson picture danhodkinson  路  3Comments