Я застрял на этом в течение последних нескольких дней и понятия не имею, что я делаю неправильно. Для целей этого вопроса я создал простой калькулятор, который умножает число от пользователя на 2.
У нас есть простой чистый редуктор, который представляет собой просто хранилище значений ключа (не лучшая структура хранения, но это не мое точка). Мы будем использовать его для хранения числа и результата:
initialState = {number: '', result: ''}
const calculatorReducer = (state = initialState, action) => {
switch (action.type) {
case CHANGE_VALUE:
return {
...state,
[action.field]: action.value
};
}
return state
}
Кстати, мы можем получить значение просто с помощью этой функции:
export const getValue = (state, field) => {
return state[field];
}
И у нас есть следующие два компонента , Родитель отвечает за логи c:
const CalculatorLogic = props => {
const evaluate = () => {
props.changeValue('result', props.getValue('number') * 2)
}
return (
<View style={styles.container}>
<MyInput name="number" onChange={evaluate}/>
<MyInput name="result" onChange={evaluate}/>
</View>
);
}
function mapStateToProps(state) {
return {
getValue: (field) => getValue(state, field),
}
}
function mapDispatchToProps(dispatch) {
return {
changeValue: (field, value) => dispatch(changeValue(field, value)),
}
}
export default connect(mapStateToProps, mapDispatchToProps)(CalculatorLogic)
Вот поле ввода, которое мы используем:
const MyInput = props => {
const valueHandler = value => {
if (props.value != value) { // user changed a value?
props.changeValue(props.name, value) // then change it in state
props.onChange() // and call evaluate function in parent
}
}
return (
<View style={{padding: 20}}>
<Text>Field {props.name}</Text>
<TextInput
style={{width: 200, border: 1}}
onChangeText={valueHandler}
value={props.value ? props.value.toString() : ''}
/>
</View>
);
}
function mapStateToProps(state, ownProps) {
return {
value: getValue(state, ownProps.name),
}
}
function mapDispatchToProps(dispatch) {
return {
changeValue: (field, value) => dispatch(changeValue(field, value)),
}
}
export default connect(mapStateToProps, mapDispatchToProps)(MyInput)
Мой вопрос: почему он рендерит поздно?
Например:
- Пользователь нажимает номер 7, ничего не происходит (должно отображаться 14, что равно 7 * 2).
- Затем пользователь вводит 5 и показывает 14 (7 раз 2 вместо 75 раз два).
- Затем пользователь вводит 3, и он показывает 150 (75 раз 2 вместо 753 раза два)
Et c.
Почему он использует старое состояние вместо текущего? Что я делаю неправильно? (Да, я хочу сохранить логин в родительском компоненте)
Спасибо !!!