В последнее время я работал в редуксе и пытался взять себя в руки, я пробовал асинхронный вызов с помощью редукс-преобразователя.
Я показываю соответствующие файлы.
Posts.js
Этот файл вызывает getPosts() в componentdidmount, который в свою очередь пытается получить данные от actionCreator.
import React,{Component} from 'react'
import Axios from 'axios'
import CardPost from '../Post/Post'
import Container from 'react-bootstrap/Container'
import Row from 'react-bootstrap/Row'
import Col from 'react-bootstrap/Col'
import classes from './Posts.module.css'
import {Link,Route} from 'react-router-dom'
import {connect} from 'react-redux'
import {getPost} from '../../Store/action/posts'
class Posts extends Component{
componentDidMount(){
this.props.getPosts()
}
render(){
let post =<p>Loading data...</p>
if (this.props.bulkPost.length>0){
console.info("rendering again")
post = this.props.bulkPost.map((item)=>{
return(
<Col as = {Link} to = {"/posts/"+item.id} className = {classes.topMargin} key = {item.id} sm = {4}>
<CardPost/>
</Col>
)
})
}
return(
<>
<div>
<Container>
<Row>
{post}
</Row>
</Container>
</div>
</>
)
}
}
const mapStateToProps = state=>{
return{
bulkPost: state.pos.posts,
// oneLineData: state.full.fetchedText
}
}
const mapDispatchToProps = dispatch =>{
return{
// onDeleteResult: (id)=>dispatch(actionCreator.deleteResult(id)),
getPosts:()=>dispatch(getPost())
}
}
export default connect(mapStateToProps, mapDispatchToProps)(Posts)
Это мой actionCreator
сообщения.js
Он использует промежуточное ПО redux thunk и пытается получить данные асинхронно, при проверке с помощью console.info(res) данные извлекаются из файла.
import {POSTS} from '../action/actionType'
import Axios from 'axios'
export const savePost = (res)=>{
return{
posts: res,
type:POSTS
}
}
export const getPost = ()=>{
return (dispatch)=>{
Axios.get("https://jsonplaceholder.typicode.com/posts/").then((response)=>{
dispatch(savePost(response.data));
})
}
}
А теперь третий файл, куда данные в идеале должны быть отправлены, и должны быть возвращены нам
import * as actionType from '../action/actionType'
const intitalState = {
posts:[]
}
const reducer = (state=intitalState, action)=>{
switch(action.type){
case actionType.POSTS:
console.info(state)
const post = state.posts.slice(0,4);
const updatedPost = post.map((post)=>{
return{
...post
}
})
return{
...state,
posts:updatedPost
}
}
return state
}
export default reducer
Здесь сообщения о состоянии не заполняются методом отправки в первом файле.
Может кто-нибудь, пожалуйста, помогите, что я здесь делаю не так?
Редактировать:
это полностью рабочий проект онлайн
https://codesandbox.io/s/4xwlwl70v0
Да, я использовал его в actionCreator, так как избыточность всегда синхронизируется, поэтому сделайте ее асинхронной. Поправьте меня, если я ошибаюсь, я действительно новичок в редуксе /\
Это верно, Redux не может обрабатывать асинхронный JavaScript из коробки, и это цель промежуточного программного обеспечения, такого как Redux Thunk.
В вашем actioncreator вы можете отправить действие напрямую:
import Axios from 'axios'
import {POSTS} from '../action/actionType'
export const getPost = ()=>{
return (dispatch)=>{
Axios.get("https://jsonplaceholder.typicode.com/posts/").then((response)=>{
dispatch({
type: POSTS,
posts: response.data
});
})
}
}
В вашем редюсере вы сопоставляете результаты вызова API. Я не вижу цели отображения результата? Посты от создателя экшена доступны на action.posts.
import * as actionType from '../action/actionType'
const initalState = {
posts: []
}
const reducer = (state = initalState, action)=>{
switch(action.type){
case actionType.POSTS:
const posts = action.posts.slice(0,4);
return{
...state,
posts: posts
}
}
return state
}
export default reducer;
Не видя ваших комбинированных Recduers, это опечатка?
const mapStateToProps = state=>{
return{
bulkPost: state.pos.posts, // maybe state.post.posts ?
// oneLineData: state.full.fetchedText
}
}
Нет, я объединил их, у меня есть ссылка в посте, которая ссылается на онлайн-оболочку разработки, вы можете видеть, что я объединил оба
Я сопоставил результат, потому что избыточность не поддерживает асинхронные вызовы, поэтому результат должен быть сопоставлен, см. Моя концепция может быть немного нарушена, но я думаю, что это должно быть
Вам не нужно отображать результат. По умолчанию создатели действий Redux не поддерживают асинхронные действия, такие как выборка данных, поэтому вы используете преобразователь. Я применил свои изменения к вашему коду, и он работает, codeandbox.io/s/r772pov6zp.
В вашем редюсере const post = state.posts.slice(0,4); state.posts — пустой массив. Вот почему вы никогда не получите никаких сообщений обратно в компонент
Вау, ты спасатель, дай мне посмотреть в коде, что я сделал не так
Это была такая ладонь лица, это был такой плохой вопрос, вчера я действительно запутался в редуксе, это может быть результатом этого. Спасибо за помощь. :-D
Чего я здесь не вижу, так это того, что вы используете промежуточное программное обеспечение, такое как
redux-thunk
, поскольку сейчас вы создаете создателей асинхронных действий, но, похоже, у вас уже есть ответ.