我正在尝试实现一个使用 react 和 redux 的社交媒体网站。
基本上我所做的是将它们存储为单独的组件,然后我正在做一些其他的事情。
然而,奇怪的是,当操作完成时,当我打印出 this
时,它显示了我想要的正确状态。但是,如果我尝试访问箭头函数中的道具,它不会更新状态。
直接使用 this
socketSend = () => {
console.log(this);
};
道具显示:
{
"isLoading": false,
"posts": [
{
"id": 262,
"likes": [],
"comments": [],
"author": "root",
"content": "fef",
"date": "2021-01-04T01:16:36.930345Z"
},
{
"id": 261,
"likes": [],
"comments": [],
"author": "root",
"content": "dd",
"date": "2021-01-04T01:08:33.835076Z"
},
{
"id": 260,
"likes": [],
"comments": [],
"author": "root",
"content": "fef",
"date": "2021-01-04T01:07:26.989194Z"
},
{
"id": 259,
"likes": [],
"comments": [],
"author": "root",
"content": "fefef",
"date": "2021-01-04T01:02:52.863209Z"
}
],
"user": {
"id": 1,
....
"last_login": "2021-01-04T00:25:57.172668Z",
"is_superuser": true,
"username": "root",
"first_name": "Root",
"last_name": "Admin",
"is_active": true,
"is_admin": false,
"verified": false,
"is_staff": true,
"groups": [],
"user_permissions": [],
"blocked_users": [],
"friends": []
},
"post": {
"id": 262,
"likes": [],
"comments": [],
"author": "root",
"content": "fef",
"date": "2021-01-04T01:16:36.930345Z"
}
}
这正是我想要的。但是,如果尝试直接访问post对象,即console.log(this.props.post)
,它会返回一个空对象({}
)
注意post
应该仅在点击撰写按钮时更新。
相关代码如下:
Feed.js
import React, { Component, Fragment } from "react";
import Preloader from "../../Preloaders/Preloader";
import AlbumsHelpModal from "./AlbumsHelpModal";
import AlbumsModal from "./AlbumsModal";
import ComposeCard from "./ComposeCard";
import CreateGroupModal from "./CreateGroupModal";
import FeedPost from "./FeedPost";
import NoStreamModal from "./NoStreamModal";
import ShareModal from "./ShareModal";
import VideosHelpModal from "./VideosHelpModal";
import VideosModal from "./VideosModal";
import BirthdayWidget from "./Widgets/BirthdayWidget";
import StoresWidget from "./Widgets/StoresWidget";
import SuggestedFriendsWidget from "./Widgets/SuggestedFriendsWidget";
import { init, initPageloader } from "./actions";
import { ChevronRight, HelpCircle } from "react-feather";
import { initSidebar } from "./actions/feedActions";
import { getPosts } from "../../../actions/posting";
import SocketInstance from "../../../websocket/socket";
import { connect } from "react-redux";
import PropTypes from "prop-types";
import { post } from "jquery";
export class Feed extends Component {
static propTypes = {
isLoading: PropTypes.bool.isRequired,
getPosts: PropTypes.func.isRequired,
posts: PropTypes.array.isRequired,
post: PropTypes.object,
};
// constructor() {
// this.initializeSocket();
// }
state = {
posts: [],
};
componentDidMount() {
this.initializeSocket();
}
initializeSocket() {
this.socketConnection(() => {
this.props.getPosts();
});
SocketInstance.connect("");
}
socketConnection(callback) {
const component = this;
setTimeout(function () {
if (SocketInstance.state() === 1) {
console.log("Connection is made");
callback();
return;
} else {
console.log("wait for connection...");
component.socketConnection(callback);
}
}, 1000);
}
socketSend = () => {
console.log(this.props.post);
// SocketInstance.send();
};
render() {
const { isLoading } = this.props;
return (
<Fragment>
<div id="main-feed" className="container">
<Preloader />
<div
id="activity-feed"
className={`view-wrap true-dom ${isLoading ? "is-hidden" : ""}`}
>
<div className="columns">
<div class="column is-3 is-hidden-mobile">
<div className="feed-menu-v1">
<ul className="main-menu">
<li className="is-active">
<a>
<i data-feather="activity"></i>
<span>Feed</span>
<span className="close-icon">
<ChevronRight />
</span>
</a>
<ul className="submenu">
<li className="is-subactive">
<a>
Trending <span className="tag">4</span>
</a>
</li>
<li>
<a>Popular</a>
</li>
<li>
<a>Following</a>
</li>
</ul>
</li>
<li>
<a>
<HelpCircle />
<span>Questions</span>
<span className="close-icon">
<ChevronRight />
</span>
</a>
<ul className="submenu">
<li>
<a>Home</a>
</li>
<li>
<a>My Questions</a>
</li>
<li>
<a>Popular</a>
</li>
</ul>
</li>
<li>
<a>
<i data-feather="youtube"></i>
<span>Videos</span>
<span className="close-icon">
<ChevronRight />
</span>
</a>
<ul className="submenu">
<li>
<a>
Home<span className="tag">7</span>
</a>
</li>
<li>
<a>Suggested</a>
</li>
<li>
<a>My Channel</a>
</li>
</ul>
</li>
<li>
<a>
<i data-feather="music"></i>
<span>Music</span>
<span className="close-icon">
<ChevronRight />
</span>
</a>
<ul className="submenu">
<li>
<a>My Products</a>
</li>
<li>
<a>
Trending<span className="tag">6</span>
</a>
</li>
<li>
<a>Popular</a>
</li>
</ul>
</li>
</ul>
</div>
</div>{" "}
<div className="column is-6">
<ComposeCard clicked={this.socketSend} />
{/* <FeedPost />
<FeedPost />
<FeedPost /> */}
{this.props.posts.map((post) => (
<FeedPost
key={post.id}
likes={post.likes}
comments={post.comments}
date={post.date}
id={post.id}
socket={this.socketSend}
author={post.author}
>
{post.content}
</FeedPost>
))}
</div>
<div class="column is-3">
<StoresWidget />
<BirthdayWidget />
<SuggestedFriendsWidget />
</div>
</div>
</div>
</div>
<CreateGroupModal />
<AlbumsHelpModal />
<AlbumsModal />
<VideosHelpModal />
<VideosModal />
<ShareModal />
<NoStreamModal />
</Fragment>
);
}
}
const mapStateToProps = (state) => ({
isLoading: state.auth.loading,
posts: state.posting.posts,
user: state.auth.user,
post: state.posting.post,
});
export default connect(mapStateToProps, { getPosts })(Feed);
ComposeCard.js
import React, { Component } from "react";
import {
Edit3,
Image,
Video,
X,
Camera,
Search,
MapPin,
Link2,
Tag,
MoreHorizontal,
MoreVertical,
} from "react-feather";
import PropTypes from "prop-types";
import { connect } from "react-redux";
import {
openPublishWindow,
closePublishWindow,
openExtendedOptions,
} from "../../../actions/feed";
import { createPost } from "../../../actions/posting";
import SocketInstance from "../../../websocket/socket";
const initialState = {
content: "",
publishDisabled: true,
composeFriends: false,
composeSearch: false,
showTagSub: false,
};
export class ComposeCard extends Component {
static propTypes = {
openPublishWindow: PropTypes.func,
closePublishWindow: PropTypes.func,
opened: PropTypes.bool,
extendFormShow: PropTypes.bool,
openExtendedOptions: PropTypes.func,
createPost: PropTypes.func,
};
state = {
content: "",
publishDisabled: true,
composeFriends: false,
composeSearch: false,
showTagSub: false,
};
handleChange = (input) => (e) => {
let val = e.target.value.trim();
// console.log(e.target.value);
// TODO: Disallow whitespace (trailing)
if (val.length >= 1) {
this.setState({
publishDisabled: false,
});
} else {
this.setState({
publishDisabled: true,
});
}
this.setState({ [input]: e.target.value });
};
submit = (e) => {
e.preventDefault();
const { content } = this.state;
const body = { content };
this.props.createPost(body);
// clear the state
this.setState({ ...initialState });
this.props.closePublishWindow();
// console.log(this.props.post);
this.props.clicked();
};
closeForm = () => {
const { extendFormShow } = this.props;
this.props.closePublishWindow();
if (extendFormShow) {
this.props.openExtendedOptions();
}
};
expandComposeFriends = () => {
this.setState({
composeFriends: true,
});
};
toggleComposeSearch = () => {
this.setState({
composeSearch: !this.state.composeSearch,
});
};
render() {
const { opened, openPublishWindow, extendFormShow } = this.props;
const {
publishDisabled,
composeFriends,
composeSearch,
showTagSub,
showActivities,
content,
shoWMoodSub,
showLocationSub,
showURLSub,
showGIFSub,
} = this.state;
return (
<div
id="compose-card"
class={`card is-new-content ${opened ? "is-highlighted" : ""}`}
>
{/* <!-- Top tabs --> */}
<div class="tabs-wrapper">
<div class="tabs is-boxed is-fullwidth">
<ul>
<li class="is-active">
<a>
<span class="icon is-small">
<Edit3 />
</span>
<span>Publish</span>
</a>
</li>
<li>
<a class="modal-trigger" data-modal="albums-help-modal">
<span class="icon is-small">
<Image />
</span>
<span>Albums</span>
</a>
</li>
<li>
<a class="modal-trigger" data-modal="videos-help-modal">
<span class="icon is-small">
<Video />
</span>
<span>Video</span>
</a>
</li>
{/* <!-- Close X button --> */}
<li class="close-wrap">
<span class="close-publish" onClick={this.closeForm}>
<X />
</span>
</li>
</ul>
</div>
{/* <!-- Tab content --> */}
<form class="tab-content" onSubmit={this.submit}>
{/* <!-- Compose form --> */}
<div class="compose">
<div class="compose-form">
<img
src="https://via.placeholder.com/300x300"
data-demo-src="assets/img/avatars/jenna.png"
alt=""
/>
<div class="control">
<textarea
id="content"
class="textarea"
onChange={this.handleChange("content")}
rows="3"
placeholder="Write something about you..."
onClick={openPublishWindow}
value={content}
></textarea>
</div>
</div>
<div id="feed-upload" class="feed-upload"></div>
<div id="options-summary" class="options-summary"></div>
</div>
<div
id="basic-options"
class={`compose-options ${extendFormShow ? "is-hidden" : ""}`}
>
{/* <!-- Upload action --> */}
<div class="compose-option">
<Camera />
<span>Media</span>
<input
id="feed-upload-input-2"
type="file"
type="file"
accept=".png, .jpg, .jpeg"
onchange="readURL(this)"
/>
</div>
</div>
{/* <!-- Footer buttons --> */}
<div class="more-wrap">
{/* <!-- View more button --> */}
{/* <!-- Publish button --> */}
<button
id="publish-button"
type="submit"
class={`button is-solid accent-button is-fullwidth ${
!publishDisabled ? "" : "is-disabled"
}`}
>
Publish
</button>
</div>
</form>
</div>
</div>
);
}
}
const mapStateToProps = (state) => ({
opened: state.feed.opened,
extendFormShow: state.feed.extendFormShow,
post: state.posting.post,
posts: state.posting.posts,
});
export default connect(mapStateToProps, {
openPublishWindow,
closePublishWindow,
openExtendedOptions,
createPost,
})(ComposeCard);