createAsyncThunk 的问题
Problems with createAsyncThunk
我刚刚在 Codecademy 上完成了 Learn Redux,想在实践中掌握这些知识。但是我有一个错误。当我创建 extraReducers
以将状态更新为实际承诺状态时,它不会添加信息。
getUserSlice.js
import { createAsyncThunk, createSlice } from '@reduxjs/toolkit';
import { fetchUserInfo } from '../../api';
export const loadUser = createAsyncThunk("getUser/loadUser",
async (arg, thunkAPI) => {
return await fetchUserInfo();
}
});
const sliceOptions = {
name: 'getUser',
initialState: {
info: [],
isLoading: false,
hasError: false,
},
reducers: {},
extraReducers: (builder) => {
builder
.addCase(loadUser.pending, (state) => {
state.isLoading = true;
state.hasError = false;
})
.addCase(loadUser.fulfilled, (state, action) => {
state.info.push(action.payload)
state.isLoading = false;
state.hasError = false;
})
.addCase(loadUser.rejected, (state, action) => {
state.isLoading = false;
state.hasError = true;
})
},
};
export const getUserSlice = createSlice(sliceOptions);
console.log(getUserSlice);
export const selectUserInfo = (state) => {
console.log(state);
return state;
};
export default getUserSlice.reducer;
api.js
export const fetchUserInfo = async () => {
const user = await fetch('http://localhost:5000/api/user');
const json = user.json();
return json;
}
App.js
import React from 'react';
import './App.css';
import {Container} from 'react-bootstrap';
import Achievement from './components/Achievement/Achievement';
import { useSelector } from 'react-redux';
import { selectUserInfo } from './features/getUser/getUserSlice';
const colors = ['#010626','#4d6396', '#5d1a87', '#5d1a87', '#5d1a87'];
function App() {
let color= colors[0];
const user = useSelector(selectUserInfo)
function changeColor() {
const newColor = `rgb(${Math.round(Math.random() *256)}, ${Math.round(Math.random() *256)}, ${Math.round(Math.random() *256)})`;
color = newColor;
}
return (
<div className="App" style={{ background: color }}>
<Container>
<h1 id="whoAmI">
Witaj na moim portfolio
{user}
</h1>
<button onClick={changeColor}>
Zmień kolor tła
</button>
<div className="col-lg-4 col-md-6 col-sm-12">
<Achievement title="Ukończenie The Web Developer Bootcamp" picture="https://res.cloudinary.com/syberiancats/image/upload/v1630317595/k9g0nox2fyexxawg8whu.jpg" />
</div>
</Container>
</div>
);
}
export default App;
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import { Provider } from 'react-redux';
import reportWebVitals from './reportWebVitals';
import { store } from './store';
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
);
reportWebVitals();
store.js
import { configureStore } from "@reduxjs/toolkit";
import getUserReducer from "./features/getUser/getUserSlice";
export const store = configureStore({
reducer: {
getUser: getUserReducer
}
})
Console.log 的 getUserSlice 和选择器中的状态
也许您可以在 extraReducer
中使用 (builder) => {}
函数并编辑您的 loadUser
因为您的 Api.js
已经 return json
代码以下:
import { createAsyncThunk, createSlice } from '@reduxjs/toolkit';
import { fetchUserInfo } from '../../api';
export const loadUser = createAsyncThunk('getUser/loadUser', async (arg, thunkAPI) => {
return await fetchUserInfo();
});
const sliceOptions = {
name: 'getUser',
initialState: {
info: [],
isLoading: false,
hasError: false,
},
reducers: {},
extraReducers: (builder) => {
builder
.addCase(loadUser.pending, (state) => {
state.isLoading = true;
state.hasError = false;
})
.addCase(loadUser.fulfilled, (state, action) => {
state.info.push(action.payload)
state.isLoading = false;
state.hasError = false;
})
.addCase(loadUser.rejected, (state, action) => {
state.isLoading = false;
state.hasError = true;
})
},
};
export const getUserSlice = createSlice(sliceOptions);
console.log(getUserSlice);
export const selectUserInfo = (state) => {
console.log(state);
return state;
};
export default getUserSlice.reducer;
你可能忘记在fetch
之前添加await
,你应该将api.js
中的抓取数据编辑成下面这样:
export const fetchUserInfo = async () => {
const user = await fetch('http://localhost:5000/api/user');
const json = user.json();
return json;
}
您可以隐式 return 并绕过 Promise 结果。类似于:
(arg, thunkAPI) => fetchUserInfo();
但是,我会采取“循序渐进”的方式:
export const loadUser = createAsyncThunk("getUser/loadUser",
async (arg, tunkApi) => {
try {
const response = await fetchUserInfo();
return response;
} catch (e) {
return thunkApi.rejectWithValue(e)
}
}
});
我刚刚在 Codecademy 上完成了 Learn Redux,想在实践中掌握这些知识。但是我有一个错误。当我创建 extraReducers
以将状态更新为实际承诺状态时,它不会添加信息。
getUserSlice.js
import { createAsyncThunk, createSlice } from '@reduxjs/toolkit';
import { fetchUserInfo } from '../../api';
export const loadUser = createAsyncThunk("getUser/loadUser",
async (arg, thunkAPI) => {
return await fetchUserInfo();
}
});
const sliceOptions = {
name: 'getUser',
initialState: {
info: [],
isLoading: false,
hasError: false,
},
reducers: {},
extraReducers: (builder) => {
builder
.addCase(loadUser.pending, (state) => {
state.isLoading = true;
state.hasError = false;
})
.addCase(loadUser.fulfilled, (state, action) => {
state.info.push(action.payload)
state.isLoading = false;
state.hasError = false;
})
.addCase(loadUser.rejected, (state, action) => {
state.isLoading = false;
state.hasError = true;
})
},
};
export const getUserSlice = createSlice(sliceOptions);
console.log(getUserSlice);
export const selectUserInfo = (state) => {
console.log(state);
return state;
};
export default getUserSlice.reducer;
api.js
export const fetchUserInfo = async () => {
const user = await fetch('http://localhost:5000/api/user');
const json = user.json();
return json;
}
App.js
import React from 'react';
import './App.css';
import {Container} from 'react-bootstrap';
import Achievement from './components/Achievement/Achievement';
import { useSelector } from 'react-redux';
import { selectUserInfo } from './features/getUser/getUserSlice';
const colors = ['#010626','#4d6396', '#5d1a87', '#5d1a87', '#5d1a87'];
function App() {
let color= colors[0];
const user = useSelector(selectUserInfo)
function changeColor() {
const newColor = `rgb(${Math.round(Math.random() *256)}, ${Math.round(Math.random() *256)}, ${Math.round(Math.random() *256)})`;
color = newColor;
}
return (
<div className="App" style={{ background: color }}>
<Container>
<h1 id="whoAmI">
Witaj na moim portfolio
{user}
</h1>
<button onClick={changeColor}>
Zmień kolor tła
</button>
<div className="col-lg-4 col-md-6 col-sm-12">
<Achievement title="Ukończenie The Web Developer Bootcamp" picture="https://res.cloudinary.com/syberiancats/image/upload/v1630317595/k9g0nox2fyexxawg8whu.jpg" />
</div>
</Container>
</div>
);
}
export default App;
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import { Provider } from 'react-redux';
import reportWebVitals from './reportWebVitals';
import { store } from './store';
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
);
reportWebVitals();
store.js
import { configureStore } from "@reduxjs/toolkit";
import getUserReducer from "./features/getUser/getUserSlice";
export const store = configureStore({
reducer: {
getUser: getUserReducer
}
})
Console.log 的 getUserSlice 和选择器中的状态
也许您可以在 extraReducer
中使用 (builder) => {}
函数并编辑您的 loadUser
因为您的 Api.js
已经 return json
代码以下:
import { createAsyncThunk, createSlice } from '@reduxjs/toolkit';
import { fetchUserInfo } from '../../api';
export const loadUser = createAsyncThunk('getUser/loadUser', async (arg, thunkAPI) => {
return await fetchUserInfo();
});
const sliceOptions = {
name: 'getUser',
initialState: {
info: [],
isLoading: false,
hasError: false,
},
reducers: {},
extraReducers: (builder) => {
builder
.addCase(loadUser.pending, (state) => {
state.isLoading = true;
state.hasError = false;
})
.addCase(loadUser.fulfilled, (state, action) => {
state.info.push(action.payload)
state.isLoading = false;
state.hasError = false;
})
.addCase(loadUser.rejected, (state, action) => {
state.isLoading = false;
state.hasError = true;
})
},
};
export const getUserSlice = createSlice(sliceOptions);
console.log(getUserSlice);
export const selectUserInfo = (state) => {
console.log(state);
return state;
};
export default getUserSlice.reducer;
你可能忘记在fetch
之前添加await
,你应该将api.js
中的抓取数据编辑成下面这样:
export const fetchUserInfo = async () => {
const user = await fetch('http://localhost:5000/api/user');
const json = user.json();
return json;
}
您可以隐式 return 并绕过 Promise 结果。类似于:
(arg, thunkAPI) => fetchUserInfo();
但是,我会采取“循序渐进”的方式:
export const loadUser = createAsyncThunk("getUser/loadUser",
async (arg, tunkApi) => {
try {
const response = await fetchUserInfo();
return response;
} catch (e) {
return thunkApi.rejectWithValue(e)
}
}
});