我正在尝试遵循ReactJS在任何状态更改可能时使用状态组件的最佳实践,并在组件无状态时支持,但我不确定我应该如何构造组件以允许两者类型。目前我正在获取JSON文件并在状态组件中设置单个对象,然后我想为每条信息构建该信息的设计和布局以及各个支柱组件,我认为这是最佳实践,但是道具组件是渲染错误,我传递的属性是undefined
。这是父/子组件问题吗?
以下是我的观看Feed(顶层,正在渲染):
export default class CommentFeed extends React.Component {
render() {
return (
<div className="comment-feed">
<Comments />
</div>
);
}
}
然后我的提取并设置为状态组件:
//Comments List
class Comments extends React.Component{
constructor(props, context) {
super(props, context);
this.state = this.context.data || window.__INITIAL_STATE__ || {users: []};
}
fetchList() {
fetch('http://localhost:3000/api/test')
.then(res => {
return res.json();
})
.then(data => {
console.log(data);
let users = data.map((user, index) => {
return(
<div key={index}>
<UserTitle title={user.title} />
<li>{user.discovery}</li>
<ul>
{
user.user_comments.map((comment, i) => {
console.log("this is the comment " + JSON.stringify(comment));
console.log("this is the i " + i);
return (
<div key={comment.userCommentId}>
<h4>{comment.app_user.fullNameSlug}</h4>
<li>{comment.comment}</li>
</div>
)
})
}
</ul>
</div>
)
})
this.setState({ users: users });
})
.catch(err => {
console.log(err);
});
}
componentDidMount() {
this.fetchList();
}
render() {
return (
<div>
<h2>Comments List</h2>
<ul>
{this.state.users}
</ul>
</div>
)
}
};
以下是<UserTitle />
道具组件:
class UserTitle extends React.Component{
render(props){
return (
<div className="test">
<h1>{props.title}</h1>
</div>
)
}
}
答案 0 :(得分:3)
您正在考虑将组件拆分为单用途组件。
一般来说,&#34;社区&#34;我们通常有两种类型的组件:
容器组件应该处理业务逻辑,获取数据,操作等,然后将需要数据作为道具传递给视图组件。
查看组件,不处理数据,不提取,只显示视图。大多数人甚至没有自己的状态(并不总是)
所以这里是您需要的简要视图: - CommentsContainer - CommentsFeedView - CommentView
它应该在代码中看起来如何:
sudo apt-get remove php5 php5-common php5-mysql php5-xmlrpc php5-cgi php5-curl php5-gd php5-cli php5-fpm php-apc php-pear php5-dev php5-imap php5-mcrypt
如果您想创建嵌套地图,则需要更改您的思维模式。 将组件视为呈现内容的黑盒子。 可能有更复杂的组件而且更少。呈现其他组件和一个内衬的组件。
所以这是一个例子,就像你的问题代码一样:
class CommentsContainer extends Component {
constructor(props) {
super(props)
this.state = {
comments = [],
loading: false
}
}
componentDidMount() {
someAjaxCall('get', '/comments')
.then(data => {
this.setState({comments: data, loading: false})
}).bind(this)
}
render() {
return <CommentsFeedView {...this.state} />
}
}
const CommentsFeedView = props => {
return (
<div>
{props.comments.map(comment => <CommentView {...comment} />}
</div>
)
}
const CommentView = props => {
return (
<div>
<h4>{props.title}</h4>
<p>{props.content}</p>
</div>
)
}
正如您在此处所看到的,我们并不十分关心地图或嵌套地图。每个组件都会呈现自己,而不关心&#34;外部&#34;
答案 1 :(得分:0)
UserTitle
和<ul>{user.user_comments.map(...)}</ul>
似乎是同一个User
组件(您希望的名称)的一部分。
而不是在回调中呈现组件(不建议因为您将组件保存到状态),我的建议是创建一个单独的组件来处理所有用户的详细信息。
它使您的代码和组件可以重用(例如UserTitle
)并且可以测试,更不用说每次用户必须以某种方式更改时都必须更新大then(data =>...)
业务逻辑。
const UserComments = ({ comments }) =>
<ul>
{comments.map(comment =>
<li key={comment.userCommentId}>
<h4>{comment.app_user.fullNameSlug}</h4>
<span>{comment.comment}</span>
</li>
)}
</ul>
const User = ({ user }) =>
<div>
<UserTitle={user.title} />
<span>{user.discovery}</span>
<UserComments comments={user.user_comments} />
</div>
在fetchList
上,您可以将用户数组保存在状态:
fetchList() {
fetch('http://localhost:3000/api/test')
.then(res => res.json())
.then(data => this.setState({ users: data }))
}
和render
:
render() {
return (
<div>
<h2>Comments List</h2>
{this.state.users.map((user, index) => <User key={index} user={user} />}
<div>
)
}