У меня проблемы с доступом к данным, возвращаемым действием Redux в виде одного объекта json. Я могу успешно получить данные и визуализировать их, но только когда я распределяю указанные данные в массив, а затем использую .map () для визуализации содержимого объекта.
Я использую действие для получения данных - Запрос GET возвращает один объект:
export const getHealthData = username => dispatch => {
dispatch(setHealthDataLoading());
axios
.get(`/api/healthData/${username}`)
.then(res =>
dispatch({
type: GET_HEALTHDATA,
payload: res.data
})
)
.catch(err =>
dispatch(returnErrors(err.response.data, err.response.status))
);
};
маршрут определяется как:
router.get("/:username", (req, res) => {
HealthData.find({
username: req.params.username
}).then(healthData => res.json(healthData));
});
В моем репозитории я вынужден распространить объект в массив, например, или иначе я не могу получить к нему доступ.
const initialState = {
healthData: [],
loading: false,
sex: "",
age: "",
height: "",
weight: "",
goal: "",
activityLevel: ""
};
export default function(state = initialState, action) {
switch (action.type) {
case GET_HEALTHDATA:
return {
...state,
healthData: [...action.payload],
loading: false
};
index. js
const rootReducer = combineReducers({
router: connectRouter(history),
item: itemReducer,
error: errorReducer,
auth: authReducer,
fatLog: fatLogReducer,
register: registerReducer,
loading: loadingReducer,
healthData: healthDataReducer
});
export default rootReducer;
Затем я могу отобразить эти данные следующим образом:
class DailyCalorieCalc extends Component {
constructor(props) {
super(props);
this.state = {
weight: "1",
height: "1",
activityLevel: "1",
goal: "1"
};
}
static propTypes = {
isAuthenticated: PropTypes.bool,
healthData: PropTypes.object,
user: PropTypes.object
};
componentDidMount() {
//const { healthData, username } = this.props;
this.props.getHealthData(this.props.user.name);
}
render() {
const { healthData } = this.props;
return (
<div>
<div>Welcome {this.props.user.name}</div>
{healthData.map(healthData => {
return (
<div className="tableBox">
<div className="hlthDataCol">
<div className="label">Sex</div>
<div className="data">{healthData.sex}</div>
</div>
<div className="hlthDataCol">
<div className="label">Weight</div>
<div className="data">{healthData.weight}</div>
</div>
<div className="hlthDataCol">
<div className="label">Height</div>
<div className="data">{healthData.height}</div>
</div>
<div className="hlthDataCol">
<div className="label">Activity Level</div>
<div className="data">{healthData.activityLevel}</div>
</div>
<div className="hlthDataCol">
<div className="label">Goal</div>
<div className="data">{healthData.goal}</div>
</div>
</div>
);
})}
</div>
);
}
}
const mapStateToProps = state => ({
isAuthenticated: state.auth.isAuthenticated,
user: state.auth.user,
healthData: state.healthData.healthData
});
export default connect(mapStateToProps, {
getHealthData
})(DailyCalorieCalc);
НО , Я бы предпочел изменить свое хранилище Redux так, чтобы healthData представлял собой всего лишь один объект (если он работал, но это не так):
const initialState = {
healthData: {},
loading: false,
sex: "",
age: "",
height: "",
weight: "",
goal: "",
activityLevel: ""
};
export default function(state = initialState, action) {
switch (action.type) {
case GET_HEALTHDATA:
return {
...state,
healthData: action.payload,
loading: false
};
Затем я хочу иметь возможность устанавливать значения объект к локальному состоянию моего компонента в componentDidUpdate. Примерно так:
class DailyCalorieCalc extends Component {
constructor(props) {
super(props);
this.state = {
weight: "1",
height: "1",
activityLevel: "1",
goal: "1"
};
}
static propTypes = {
isAuthenticated: PropTypes.bool,
healthData: PropTypes.object,
user: PropTypes.object
};
componentDidMount() {
//const { healthData, username } = this.props;
this.props.getHealthData(this.props.user.name);
}
componentDidUpdate(prevProps, prevState) {
const { error, healthData } = this.props;
if (healthData != pervProps.healthData){
this.setState({
weight: healthData.weight,
height: healthData.height,
age: healthData.age,
goal: healthData.goal,
activityLevel: healthData.activityLevel
})
}
}
render() {
const { healthData } = this.props;
return (
<div>
<div>Welcome {this.props.user.name}</div>
{healthData.map(healthData => {
return (
<div className="tableBox">
<div className="hlthDataCol">
<div className="label">Sex</div>
<div className="data">{healthData.sex}</div>
</div>
<div className="hlthDataCol">
<div className="label">Weight</div>
<div className="data">{healthData.weight}</div>
</div>
<div className="hlthDataCol">
<div className="label">Height</div>
<div className="data">{healthData.height}</div>
</div>
<div className="hlthDataCol">
<div className="label">Activity Level</div>
<div className="data">{healthData.activityLevel}</div>
</div>
<div className="hlthDataCol">
<div className="label">Goal</div>
<div className="data">{healthData.goal}</div>
</div>
</div>
);
})}
</div>
);
}
}
const mapStateToProps = state => ({
isAuthenticated: state.auth.isAuthenticated,
user: state.auth.user,
healthData: state.healthData.healthData
});
export default connect(mapStateToProps, {
getHealthData
})(DailyCalorieCalc);
Как мне перевести значения, хранящиеся в моем объекте данных, в локальное состояние? Заранее спасибо. Приношу свои извинения за такой длинный и беспорядочный вопрос.