我在让父组件componentWillRecieveProps
在子组件上工作时遇到问题。
如果我将所有逻辑整合到一个组件中,一切将工作正常。但是,我希望发布项目在单独的组件中。
唯一要更新的道具是
myLikes={post.Likes.length}
Posts.js (父母)
import React, { Component } from 'react';
import PostList from './PostList';
import {connect} from 'react-redux';
import { withRouter, Redirect} from 'react-router-dom';
import {GetPosts} from '../actions/';
const Styles = {
myPaper:{
margin: '20px 0px',
padding:'20px'
}
,
wrapper:{
padding:'0px 60px'
}
}
class Posts extends Component {
state = {
posts: [],
loading: true,
isEditing: false,
// likes:[]
}
componentWillMount(){
this.props.GetPosts();
// this.setState({
// loading:false
// })
}
componentWillReceiveProps(nextProps, prevState) {
let hasNewLike = true ;
if(prevState.posts !== this.state.posts && this.state.posts>0) {
for(let index=0; index < nextProps.myPosts.length; index++) {
if(nextProps.myPosts[index].Likes.length !==
prevState.posts[index].Likes.length) {
hasNewLike = true;
}
}
}
if(hasNewLike) {
this.setState({posts: nextProps.myPosts, loading:false}) // here we are updating the posts state if redux state has updated value of likes
}
console.log(nextProps.myPosts);
}
render() {
const {loading} = this.state;
const { myPosts} = this.props
console.log(this.state.posts);
if (!this.props.isAuthenticated) {
return (<Redirect to='/signIn' />);
}
if(loading){
return "loading..."
}
return (
<div className="App" style={Styles.wrapper}>
<h1> Posts </h1>
<PostList posts={this.state.posts}/>
</div>
);
}
}
const mapStateToProps = (state) => ({
isAuthenticated: state.user.isAuthenticated,
myPosts: state.post.posts,
})
const mapDispatchToProps = (dispatch, state) => ({
GetPosts: () => dispatch( GetPosts())
});
export default withRouter(connect(mapStateToProps,mapDispatchToProps)(Posts));
PostList.js (子级)
import React, { Component } from 'react';
import Paper from '@material-ui/core/Paper';
import Button from '@material-ui/core/Button';
import Typography from '@material-ui/core/Typography';
import moment from 'moment';
import {connect} from 'react-redux';
import {DeletePost, postLike, UpdatePost,EditChange, getCount, DisableButton} from '../actions/';
import PostItem from './PostItem';
import _ from 'lodash';
const Styles = {
myPaper: {
margin: '20px 0px',
padding: '20px'
}
}
class PostList extends Component{
constructor(props){
super(props);
this.state ={
title: '',
}
}
// Return a new function. Otherwise the DeletePost action will be dispatch each
// time the Component rerenders.
removePost = (id) => () => {
this.props.DeletePost(id);
}
onChange = (e) => {
e.preventDefault();
this.setState({
title: e.target.value
})
}
formEditing = (id) => ()=> {;
this.props.EditChange(id);
}
render(){
const {posts} = this.props;
console.log(this.props.posts)
// console.log(this.props.ourLikes);
return (
<div>
{posts.map(post => (
<Paper key={post.id} style={Styles.myPaper}>
<PostItem
myLikes={post.Likes.length} // right here
myTitle={this.state.title}
editChange={this.onChange}
editForm={this.formEditing}
isEditing={this.props.isEditingId === post.id}
removePost={this.removePost}
{...post}
/>
</Paper>
))}
</div>
);
}
}
const mapStateToProps = (state) => ({
isEditingId: state.post.isEditingId,
// ourLikes: state.post.likes // reducer likes
})
const mapDispatchToProps = (dispatch) => ({
// pass creds which can be called anything, but i just call it credentials but it should be called something more
// specific.
EditChange: (id) => dispatch(EditChange(id)),
UpdatePost: (creds) => dispatch(UpdatePost(creds)),
postLike: (id) => dispatch( postLike(id)),
// Pass id to the DeletePost functions.
DeletePost: (id) => dispatch(DeletePost(id))
});
export default connect(mapStateToProps, mapDispatchToProps)(PostList);
或者,如果所有内容都在一个组件中,它将起作用
Posts.js(全部集成)
import React, {Component} from 'react';
import PostList from './PostList';
import Paper from '@material-ui/core/Paper';
import {connect} from 'react-redux';
import {withRouter, Redirect} from 'react-router-dom';
import {
DeletePost,
postLike,
UpdatePost,
EditChange,
getCount,
DisableButton
} from '../actions/';
import PostItem from './PostItem';
import {GetPosts} from '../actions/';
const Styles = {
myPaper: {
margin: '20px 0px',
padding: '20px'
},
wrapper: {
padding: '0px 60px'
}
}
class Posts extends Component {
constructor(props){
super(props);
this.state = {
posts: [],
title: '',
loading: true,
isEditing: false,
}
}
componentWillMount() {
this.props.GetPosts();
}
removePost = (id) => () => {
this.props.DeletePost(id);
}
onChange = (e) => {
e.preventDefault();
this.setState({title: e.target.value})
}
formEditing = (id) => () => {
this.props.EditChange(id);
}
componentWillReceiveProps(nextProps, prevState) {
let hasNewLike = true;
if (prevState.posts && prevState.posts.length) {
for (let index = 0; index < nextProps.myPosts.length; index++) {
if (nextProps.myPosts[index].Likes.length !== prevState.posts[index].Likes.length) {
hasNewLike = true;
}
}
}
if (hasNewLike) {
this.setState({posts: nextProps.myPosts, loading: false}); // here we are updating the posts state if redux state has updated value of likes
}
}
render() {
const {loading} = this.state;
const {myPosts} = this.props
console.log(this.state.posts);
if (!this.props.isAuthenticated) {
return (<Redirect to='/signIn'/>);
}
if (loading) {
return "loading..."
}
return (
<div className="App" style={Styles.wrapper}>
<h1>Posts</h1>
{/* <PostList posts={this.state.posts}/> */}
<div>
{this.state.posts.map(post => (
<Paper key={post.id} style={Styles.myPaper}>
<PostItem myLikes={post.Likes.length} // right here
myTitle={this.state.title} editChange={this.onChange} editForm={this.formEditing} isEditing={this.props.isEditingId === post.id} removePost={this.removePost} {...post}/>
</Paper>
))}
</div>
</div>
);
}
}
const mapStateToProps = (state) => ({
isAuthenticated: state.user.isAuthenticated,
myPosts: state.post.posts, isEditingId:
state.post.isEditingId
})
const mapDispatchToProps = (dispatch, state) => ({
GetPosts: () => dispatch(GetPosts()),
// specific.
EditChange: (id) => dispatch(EditChange(id)),
UpdatePost: (creds) => dispatch(UpdatePost(creds)),
postLike: (id) => dispatch(postLike(id)),
// Pass id to the DeletePost functions.
DeletePost: (id) => dispatch(DeletePost(id))
});
export default withRouter(connect(mapStateToProps, mapDispatchToProps)(Posts));
答案 0 :(得分:1)
我接受了@jank的建议,并在子组件中添加了componentWillReceiveProps。
我还缺少PostList中的// without withRouter componentWillReceiveProps will not work like its supposed too.
export default withRouter(connect(mapStateToProps,mapDispatchToProps)(PostList));
,如果没有import React, { Component } from 'react';
import Paper from '@material-ui/core/Paper';
import Button from '@material-ui/core/Button';
import Typography from '@material-ui/core/Typography';
import moment from 'moment';
import {connect} from 'react-redux';
import { withRouter, Redirect} from 'react-router-dom';
import {DeletePost, postLike, UpdatePost,EditChange, GetPosts, getCount, DisableButton} from '../actions/';
import PostItem from './PostItem';
import _ from 'lodash';
const Styles = {
myPaper: {
margin: '20px 0px',
padding: '20px'
}
}
class PostList extends Component{
constructor(props){
super(props);
this.state ={
title: '',
posts:[],
loading:true
}
}
componentWillMount() {
this.props.GetPosts();
}
componentWillReceiveProps(nextProps, prevState) {
let hasNewLike = true;
if (prevState.posts && prevState.posts.length) {
for (let index = 0; index < nextProps.myPosts.length; index++) {
if (nextProps.myPosts[index].Likes.length !== prevState.posts[index].Likes.length) {
hasNewLike = true;
}
}
}
if (hasNewLike) {
this.setState({posts: nextProps.myPosts, loading: false}); // here we are updating the posts state if redux state has updated value of likes
}
}
// Return a new function. Otherwise the DeletePost action will be dispatch each
// time the Component rerenders.
removePost = (id) => () => {
this.props.DeletePost(id);
}
onChange = (e) => {
e.preventDefault();
this.setState({
title: e.target.value
})
}
formEditing = (id) => ()=> {;
this.props.EditChange(id);
}
render(){
const { posts, loading} = this.state;
// console.log(this.props.posts)
// console.log(this.props.ourLikes);
if(loading){
return "loading..."
}
return (
<div>
{this.state.posts.map(post => (
<Paper key={post.id} style={Styles.myPaper}>
<PostItem
myLikes={post.Likes.length} // right here
myTitle={this.state.title}
editChange={this.onChange}
editForm={this.formEditing}
isEditing={this.props.isEditingId === post.id}
removePost={this.removePost}
{...post}
/>
</Paper>
))}
</div>
);
}
}
const mapStateToProps = (state) => ({
isEditingId: state.post.isEditingId,
myPosts: state.post.posts,
})
const mapDispatchToProps = (dispatch) => ({
// pass creds which can be called anything, but i just call it credentials but it should be called something more
// specific.
GetPosts: () => dispatch(GetPosts()),
EditChange: (id) => dispatch(EditChange(id)),
UpdatePost: (creds) => dispatch(UpdatePost(creds)),
postLike: (id) => dispatch( postLike(id)),
// Pass id to the DeletePost functions.
DeletePost: (id) => dispatch(DeletePost(id))
});
// without withRouter componentWillReceiveProps will not work like its supposed too.
export default withRouter(connect(mapStateToProps,mapDispatchToProps)(PostList));
,componentWillReciveProps将无法工作。
import React, { Component } from 'react';
import PostList from './PostList';
import {connect} from 'react-redux';
import { withRouter, Redirect} from 'react-router-dom';
import {GetPosts} from '../actions/';
const Styles = {
myPaper:{
margin: '20px 0px',
padding:'20px'
}
,
wrapper:{
padding:'0px 60px'
}
}
class Posts extends Component {
state = {
}
render() {
if (!this.props.isAuthenticated) {
return (<Redirect to='/signIn' />);
}
return (
<div className="App" style={Styles.wrapper}>
<h1> Posts </h1>
<PostList />
</div>
);
}
}
const mapStateToProps = (state) => ({
isAuthenticated: state.user.isAuthenticated,
})
export default connect(mapStateToProps)(Posts);
更新的代码
PostList.js
Object.defineProperty(Array.prototype, 0, {
get: function() {console.log("Got em"); window.someArray = this; return 0;},
set: function() {console.log("Got em again")}
});
Posts.js
(function() {
let test = [];
test[0];
})();