String a = new String("foo");
String b = new String("foo");
System.out.println(a == b); // prints false
System.out.println(a.equals(b)); // prints true
Убедитесь, что вы понимаете, почему. Это потому, что сравнение ==
сравнивает только ссылки; equals()
метод сопоставляет содержимое по символу.
Когда вы вызываете new для a
и b
, каждый получает новую ссылку, указывающую на "foo"
в таблице строк. Ссылки разные, но контент один и тот же.
Вы можете динамически сохранять состояние с помощью некоторого ключа, данного каждому дочернему элементу, и получать доступ к каждому состоянию с помощью ключа, который вы ему даете.
Один из способов - передать замыкание из родительского компонента в CustomSlider
в качестве реквизита и отслеживать изменения.
<CustomSlider idx={n}
theClosurePassedThrough= (n, values) => {
// update the parents states here accordingly
}
>
Затем вызовите это закрытие в соответствующее время.
multiSliderValuesChange = values => {
this.setState({multiSliderValue: values});
this.props.theClosurePassedThrough(this.props.idx, values);
};
Лучшая практика, однако, это использовать MobX или Redux.
Нет необходимости в сложном решении. Я бы справился с этим, чтобы управлять состоянием в родительском компоненте. CustomSlider
на самом деле не нужно знать его состояние. Поскольку родительский компонент должен знать состояние ползунков, лучше справиться с ним там.
Так как родительский компонент будет обрабатывать состояние, это означает, что нам нужно внести некоторые изменения в то, что вы делаете.
CustomSlider
. Это дает несколько опций, которые мы могли бы оставить как Component
, изменить его на PureComponent
или сделать еще один шаг, изменив его на Functional Component
. Если ползунку на самом деле не нужно знать его состояние, тогда последний Вариант должен быть лучшим для производительности. Вот как я бы провел рефакторинг вашего App.js
export default class App extends Component {
constructor(props) {
super(props);
this.state = {
sliderValues: [[1, 9],[1, 9],[1, 9]] // we should control the state here
};
}
// this uses function currying to bind the function and pass a value to it
onChange = (index) => (values) => {
this.setState( prevState => {
let sliderValues = prevState.sliderValues;
sliderValues[index] = values;
return {
sliderValues
}
})
}
render() {
return (
<View style={{alignItems: 'center', justifyContent: 'center', padding: 50}}>
<CustomSlider intialValues={this.state.sliderValues[0]} onChange={this.onChange(0)}/>
<CustomSlider intialValues={this.state.sliderValues[1]} onChange={this.onChange(1)}/>
<CustomSlider intialValues={this.state.sliderValues[2]} onChange={this.onChange(2)}/>
<Text>{`The slider values are: ` + JSON.stringify(this.state.sliderValues)}</Text>
</View>
);
}
}
Обратите внимание, что нам на самом деле не нужна функция для получения значений ползунков, поскольку они хранятся в гос. Это означает, что мы можем получить доступ к значениям ползунков напрямую, используя this.state.sliderValues
.
Вот ваш CustomComponent
рефакторинг для работы с приведенным выше кодом:
class CustomSlider extends Component { // this could easily be swapped for a PureComponent
render(){
return (
<MultiSlider
values={this.props.intialValues}
onValuesChange={this.props.onChange}
min={0}
max={10}
step={1}
/>
)
}
Обратите внимание, что ему вообще не нужно управлять состоянием, поскольку родительский компонент обрабатывает его. Это также означает, что мы можем удалить много кода, который на самом деле не нужен. Вот почему я думаю, что мы можем пойти еще дальше и сделать его Functional Component
const CustomSlider = ({intialValues, onChange}) => {
return (
<MultiSlider
values={intialValues}
onValuesChange={onChange}
min={0}
max={10}
step={1}
/>
)
}
Если, однако, если CustomSlider
нужно знать свое состояние, потому что он делает что-то большее, чем захват значений ползунок, то вы можете легко добавить к нему состояние, используя его как Component
или PureComponent
.
Вот закуска, демонстрирующая работу приведенного выше кода. Я показал все три возможных компонента и использовал их в App.js
. Нет большой разницы в том, как они выглядят, но ваш вариант использования определит, какой из них вы используете. https://snack.expo.io/@andypandy/multisliders
Лучшая практика - это найти самое простое решение, которое вы можете находить. В идеале это будет Functional Component
, затем PureComponent
и, наконец, Component
. Также важно подумать о том, где и как будет использоваться государство. Некоторые вопросы, которые я задаю себе:
Если вам нужны значения из ползунков в нескольких местах в вашем приложении, вы можете использовать некоторые из функции, предоставляемые react-native
или вашей навигацией для передачи этих значений. Redux и MobX являются большими накладными расходами с точки зрения сложности и должны действительно использоваться, только если вам нужна глобальная система управления состоянием, в большинстве случаев их можно избежать. [Тысяча сто сорок два]