gpt4 book ai didi

javascript - React - TypeError : this. props.courses.map 不是函数

转载 作者:数据小太阳 更新时间:2023-10-29 04:15:28 25 4
gpt4 key购买 nike

我创建了一个 react-redux 应用程序。目前它所做的是从服务器(api)加载类(class),并将它们显示到类(class)组件​​。这完美地工作。我正在尝试添加一个功能,您可以在其中通过将类(class)发布到服务器来创建类(class),然后服务器将返回一个成功对象。但是,当我发布到服务器时,出现以下错误(见下文)。我认为这是由于我的 connect 语句在监听负载类(class)操作。很明显,它认为它应该得到一个列表,而不是一个成功对象。我已经尝试了一些方法来收听类(class)和成功响应,但是为了节省您阅读我所做的所有奇怪事情的时间,我无法让它发挥作用。有谁知道如何解决这个问题?

错误

TypeError: this.props.courses.map is not a function

course.component.js
    onSave(){
// this.props.createCourse(this.state.course);
this.props.actions.createCourse(this.state.course);
}
render() {
return (
<div>
<div className="row">
<h2>Couses</h2>
{this.props.courses.map(this.courseRow)}
<input
type="text"
onChange={this.onTitleChange}
value={this.state.course.title} />
<input
type="submit"
onClick={this.onSave}
value="Save" />
</div>
</div>
);
}
}
// Error occurs here
function mapStateToProps(state, ownProps) {
return {
courses: state.courses
};
}
function mapDispatchToProps(dispatch) {
return {
actions: bindActionCreators(courseActions, dispatch)
};
}
export default connect(mapStateToProps, mapDispatchToProps)(Course);

course.actions.js
export function loadCourse(response) {
return {
type: REQUEST_POSTS,
response
};
}
export function fetchCourses() {
return dispatch => {
return fetch('http://localhost:3000/api/test')
.then(data => data.json())
.then(data => {
dispatch(loadCourse(data));
}).catch(error => {
throw (error);
});
};
}
export function createCourse(response) {
return dispatch => {
return fetch('http://localhost:3000/api/json', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({
response: response
})
})
.then(data => data.json())
.then(data => {
dispatch(loadCourse(data));
}).catch(error => {
throw (error);
});
};
}

course.reducer.js
export default function courseReducer(state = [], action) {
switch (action.type) {
case 'REQUEST_POSTS':
return action.response;
default:
return state;
}
}

服务器.js
router.get('/test', function(req, res, next) {
res.json(courses);
});

router.post('/json', function(req, res, next) {
console.log(req.body);
res.json({response: 200});
});

我曾尝试添加对状态的响应,并在 map 状态中监听它到 Prop ,但仍然出于某种原因, react 正在尝试将响应映射到类(class)。我需要第二种连接方法吗?
function mapStateToProps(state, ownProps) {
return {
courses: state.courses,
resposne: state.resposne
};
}

正如您从图片中看到的,响应被映射为类(class)而不是响应。

图片
enter image description here

最佳答案

假设:

  • state.courses最初是一个空数组 - 来自 course.reducer.js
  • 你不叫fetchCourses()第一次渲染 View 时的操作
  • 即使您拨打 fetchCourses()只要courses就没有问题server.js 中是一个数组(响应中的数组替换了初始的 state.courses )

  • 流量:
    现在我假设第一次渲染成功并且 React 显示 <input type="text">submit按钮。现在,当您输入标题并单击 submit 时按钮, onSave()方法触发 createCourse()参数或多或少类似于 { title: 'something' } 的操作.
    然后你序列化上面提到的参数并发送到服务器(在 course.actions.js -> createCourse() 中),服务器又返回一个看起来像 {response: 200} 的响应(在 server.js 中)。响应字段是一个整数和 不是 大批!走得更远你打电话 loadCourses()与对象 {response: 200}这会触发 courseReducer在 course.reducer.js courseReducer() 替换 state.courses (根据假设是 [] )一个整数。这个状态更新会触发重新渲染,你最终会调用 map()在整数上而不是在数组上,从而导致 TypeError: this.props.courses.map is not a function .
    可能的解决方案:
  • 从 serve.js 返回有效响应(即返回调用端点的 course 对象),或
  • 更新您的 reducer 以将新类(class)对象添加到现有 state.courses数组,例如,return [...state, action.response]

  • 更新:
    根据OP的评论,如果您想要做的是将新类(class)对象发送到服务器,验证它并发送成功(或错误)并根据响应将相同的类(class)对象添加到先前的类(class)列表中,那么您可以简单地调用 loadData()course您调用的对象 createCourse()在您的 reducer 中使用和(如上所述),而不是替换或改变旧数组,而是创建一个新数组并将类(class)对象附加到它,在 es6 中,您可以执行以下操作, return [...state, course] .
    更新 2:
    建议你通过 Redux's Doc .引自 Redux Actions' Doc

    Actions are payloads of information that send data from your application to your store. They are the only source of information for the store.

    createCourse()使用或多或少类似的有效载荷调用 Action , {title: 'Thing you entered in Text Field'} ,然后您使用 AJAX 请求调用您的服务器并将有效负载传递给服务器,然后服务器验证有效负载并根据您的逻辑发送成功(或错误)响应。服务器响应看起来像, {response: 200} . createCourse() 到此结束行动。现在你 dispatch() loadCourses()来自内部的行动 createCorse() ,与您从服务器收到的响应,这不是您想要的(基于您的评论)。因此,请尝试 dispatch()像这样执行操作(尝试重命名 response 参数,这有点令人困惑)
    //.....
    .then(data => {
    dispatch(loadCourse(response)); // the same payload you called createCourse with
    })
    //.....
    现在, loadCourse()是一个非常基本的操作,它只是转发参数,Redux 使用它来调用您的 reducer .现在,如果您遵循之前的讨论并更新了您如何拨打 loadCourse() ,然后从 loadCourse() 返回好像
    {
    type: REQUEST_POSTS,
    response: {
    title: 'Thing you entered in Text Field',
    }
    }
    然后传递给您的 reducer ,特别是您的 courseReducer() .
    再次引用 Redux Reducers' Doc

    Actions describe the fact that something happened, but don't specify how the application's state changes in response. This is the job of reducers.

    reducer必须定义操作应该如何影响 store 中的数据的逻辑。 .
    在您的 courseReducer() ,您只需返回 response action 内的字段object 和 [期望] Redux 自动神奇地改变你的状态!不幸的是,这不是发生的事情:(
    无论您从 reducer 返回什么,都将完全替换之前存在的任何事物/对象,例如,如果您的状态看起来像这样
    { courses: [{...}, {...}, {...}] }
    然后你从你的 reducer 返回这样的东西
    { title: 'Thing you entered in Text Field'}
    然后 redux 将更新状态看起来像
    { courses: { title: 'Thing you entered in Text Field'} }
    state.courses 不再是一个数组!
    解决方案:
    把你的 reducer 改成这样
    export default function courseReducer(state = [], action) {
    switch (action.type) {
    case 'REQUEST_POSTS':
    return [...state, action.response]
    default:
    return state
    }
    }
    旁注 :这有时可能会令人困惑,所以只是为了记录, statecourseReducer()不是完整状态,而是 propertystate reducer管理。您可以阅读有关此内容的更多信息 here

    关于javascript - React - TypeError : this. props.courses.map 不是函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44418362/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com