#javascript #reactjs #react-context
Вопрос:
Я следую учебнику, в котором они делают клон Spotify. Для этого я получил маркер доступа пользователя для доступа ко всем пользовательским данным. И чтобы избежать детализации, я использую React Context-api
для сохранения и извлечения пользовательских данных (токен, информация о пользователе, информация о списке воспроизведения и т. Д.). В моем Sidebar.js
случае я хочу извлечь информацию о списке воспроизведения из контекста слоя данных и показать ее пользователю. Но информация о плейлисте там не отображается, и после входа в консоль я получил undefined
. Чтобы быть уверенным, я также зарегистрировал информацию о плейлисте в консоли App.js
, там я получаю всю необходимую информацию, но не в Sidebar.js
. Я прикрепил скриншот того, что я получаю по этой ссылке —> >https://ibb.co/PGj4XcT , Любая помощь будет признательна.
Sidebar.js
function SideBar() {
const [{ playlists }, dispatch] = UseDataLayerValue();
console.log("user playlist from sidebar.js", playlists);
return (
<div className="sidebar">
<img
className="sidebar__logo"
src="https://getheavy.com/wp-content/uploads/2019/12/spotify2019-830x350.jpg"
alt="spotify-logo"
/>
<SidebarOption Icon={HomeIcon} title="Home" />
<SidebarOption Icon={SearchIcon} title="Search" />
<SidebarOption Icon={LibraryMusicIcon} title="Your Library" />
<br />
<strong className="sidebar__title">PLAYLISTS</strong>
<hr />
{playlists?.items?.map((list) => {
return <SidebarOption title={list.name} />;
})}
</div>
);
}
App.js
function App() {
const [{ token }, dispatch] = UseDataLayerValue();
useEffect(() => {
const hash = getTokenFromUrl;
window.location.hash = "";
const _token = hash.access_token;
if (_token) {
dispatch({
type: "SET_TOKEN",
token: _token,
});
// setToken(_token);
spotify.setAccessToken(_token);
spotify.getMe().then((user) => {
dispatch({
type: "SET_USER",
user: user,
});
});
spotify.getUserPlaylists().then((playlist) => {
console.log("user playlist from app.js", playlist);
dispatch({
type: "SET_PLAYLIST",
playlists: playlist,
});
});
}
}, [dispatch]);
//console.log(user);
//console.log(token);
return (
<div className="app">
{token ? <Player spotify={spotify} /> : <Login />}
</div>
);
}
Reducer.js
export const initialState = {
user: null,
playlists: [],
playing: false,
item: null,
token: null,
};
export const reducer = (state, action) => {
switch (action.type) {
case "SET_USER":
return {
...state,
user: action.user,
};
case "SET_TOKEN":
return {
...state,
token: action.token,
};
case "SET_PLAYLIST":
return {
...state,
playlists: action.playlist,
};
default:
return state;
}
};
Комментарии:
1. В вашем редукторе есть опечатка, должно быть
playlists: action.playlists
2. @BankBuilder но по-моему
App.js
, я получаюplaylist
от обещания, не так ли? почему плейлисты? Также вSidebar.js
я получаю информацию о плейлисте, но отображение не работает3. Все остальное кажется мне правильным, но ваше сообщение выглядит так:
dispatch({type: "SET_PLAYLIST", playlists: playlist});
. Обратите внимание, что ключ в вашем действии названplaylists
(как вaction.playlists
), но в вашем редукторе вы ссылаетесь на него какaction.playlist
.4. @BankBuilder да, я понял, но отображение все равно не работает. Я зарегистрировал каждый элемент в консоли, но они не вызываются в
SidebarOption
компоненте5. @BankBuilder нет, сейчас это решено… Все , что мне нужно было сделать, это добавить
return
перед<SidebarOption title={list.name} />;
… Так как я использую фигурные скобки, вот почему я забыл добавитьreturn
, Сначала я подумал, что функция стрелки автоматически возвращает что-то, но я ошибся. Поскольку я использовал{}
это, мне пришлось добавитьreturn
перед заявлением. Я обновилSidebar.js
Ответ №1:
Все , что мне нужно было сделать, это добавить возврат до <SidebarOption title={list.name} />;
… Так как я использую фигурные скобки, вот почему я забыл добавить return
, Сначала я подумал, что функция стрелки автоматически возвращает что-то, но я ошибся. Поскольку я использовал {}
это, мне пришлось добавить return перед заявлением. Я обновил Sidebar.js