В настоящее время я создаю свое первое приложение с помощью React, и сегодня я столкнулся с проблемой, которую, по-моему, пока не могу решить самостоятельно.
Так в чем дело:
Я рендеринг контейнера Result. js, который состоит из более мелких компонентов, отображающих данные из API. Первоначально он скрыт (не отображается) и отображается после передачи запроса в компонент поиска и получения ответа. Я пытаюсь реализовать переход, чтобы он исчез (непрозрачность 0 -> 1) после ответа. Это работает нормально, но я также хочу, чтобы он исчезал, когда пользователь отправляет другой запрос и снова появляется. Это то, что не работает, или рабочие части. Прямо сейчас анимация затухания проигрывается, но ближе к концу появляется флаг sh более раннего состояния компонента с предыдущими данными. Как будто там был дополнительный рендер. Я пробовал разные подходы, такие как встроенный стиль (display: none), но большинство из них заканчивалось тем, что анимация затухания вообще не воспроизводилась.
Я использую Redux для хранения ответа API и свойства отображения компонентов. Код, над которым я работал, можно найти ниже. Я буду очень благодарен за любые предложения или идеи, также связанные с моим стилем кодирования / чистотой кода :) Спасибо!
Результат. js контейнер:
const Result = props => {
return (
<Transition
in={props.displayResult}
timeout={1000}
mountOnEnter
unmountOnExit
>
{state => (
<div
className={`${classes.Box} ${
state === 'entering'
? classes.ResultOpen
: state === 'entered'
? classes.ResultVisible
: state === 'exiting'
? classes.ResultClosed
: state === 'exited'
? classes.ResultVisible
: null
}`}
>
<div className={classes.BoxRow}>
<Sprites />
<NameId />
</div>
<div className={classes.BoxRow}>
<div className={classes.BoxColumn}>
<Abilities />
<Metrics />
</div>
<Types />
</div>
<div className={classes.BoxRow}>
<Stats />
</div>
</div>
)}
</Transition>
);
};
const mapStateToProps = state => {
return {
displayResult: state.result.displayResult
};
};
export default connect(mapStateToProps)(React.memo(Result));
редуктор. js
const initialState = {
id: null,
name: '',
spriteFront: '',
spriteBack: '',
types: [],
height: null,
weight: null,
stats: [],
baseExperience: null,
abilities: [],
moves: [],
displayResult: false,
error: false,
loading: false
};
const setResult = (state, action) => {
return updateObject(state, {
id: action.result.id,
name: action.result.name,
spriteFront: action.result.sprites.front_default,
spriteBack: action.result.sprites.back_default,
types: action.result.types,
height: action.result.height,
weight: action.result.weight,
stats: action.result.stats,
baseExperience: action.result.base_experience,
abilities: action.result.abilities,
moves: action.result.moves,
displayResult: true
});
};
const resetBox = (state, action) => {
return updateObject(state, {
displayResult: false
});
};
const fetchResultFailed = (state, action) => {
return updateObject(state, { error: true });
};
const reducer = (state = initialState, action) => {
switch (action.type) {
case actionTypes.SET_RESULT:
return setResult(state, action);
case actionTypes.FETCH_RESULT_FAILED:
return fetchResultFailed(state, action);
case actionTypes.RESET_BOX:
return resetBox(state, action);
default:
return state;
}
};
export default reducer;
действия. js
export const setResult = result => {
return {
type: actionTypes.SET_RESULT,
result: result
};
};
export const resetBox = () => {
return {
type: actionTypes.RESET_BOX
};
};
export const fetchResultFailed = () => {
return {
type: actionTypes.FETCH_RESULT_FAILED
};
};
export const nextResult = query => {
return dispatch => {
dispatch(resetBox());
setTimeout(() => {
dispatch(initResult(query));
}, 100);
};
};
export const initResult = query => {
return dispatch => {
axios
.get(`https://pokeapi.co/api/v2/pokemon/${query}`)
.then(response => {
dispatch(setResult(response.data));
console.log(response.data);
})
.catch(error => {
dispatch(fetchResultFailed());
});
};
};