请帮助我是新来的人。我正在尝试创建一个简单的消息传递应用程序。
当[messages]更新时,我希望MessageForm组件稍微重新呈现。它可以做到,但即使没有更新也不会停止。
我知道这一点,因为当我检查我的redux开发工具时,我不断看到一个动作
const MessageForm = ({ getMessages, addMessages, deleteMessages, messages, roomId,}) => {
useEffect(() => {
getMessages(roomId);
scrollToBottom();
}, [messages]);
const [formData, setFormData] = useState({
text: "",
});
const { text } = formData;
let messagesEnd;
const scrollToBottom = () => {
messagesEnd.scrollIntoView({ behavior: "smooth" });
};
const onChange = (e) =>
setFormData({ ...formData, [e.target.name]: e.target.value });
const onSubmit = (e) => {
e.preventDefault();
addMessages(text, roomId);
setFormData({ text: "" });
};
let user = JSON.parse(localStorage.getItem("user"));
let messageList = messages.messages.map((message) => {
return message.user === user._id ? (
<div className="row">
<div className="container darker col-6" key={message._id}>
<div className="username"> {message.name}</div>
<Avatar
size="50"
round={true}
src={message.avatar}
className="right"
/>
<p>{message.text.toString()}</p>
<span className="time-left">
{moments(message.createdAt).format("LLL")}
</span>
<span className="time-right">
<Icon
onClick={() => {
deleteMessages(message._id);
}}
name="trash alternate"
className="trashCan"
/>
</span>
</div>
</div>
) : (
<div className="row justify-content-end">
<div className="container darker senders col-6 " key={message._id}>
<div className="username"> {message.name}</div>
<Avatar
size="50"
round={true}
src={message.avatar}
className="right"
/>
<p>{message.text.toString()}</p>
<span className="time-left">
{moments(message.createdAt).format("LLL")}
</span>
<span className="time-right">
<Icon
onClick={() => {
deleteMessages(message._id);
}}
name="trash alternate"
className="trashCan"
/>
</span>
</div>
</div>
);
});
return (
<div className="messageArea">
<div className="textarea">
{messageList}
<div
style={{ float: "left", clear: "both" }}
ref={(el) => {
messagesEnd = el;
}}
></div>
</div>
<form className="row inputBox" onSubmit={onSubmit}>
<div className="col-10">
<input
type="text"
className="form-control"
placeholder="Enter Message"
aria-label="Enter Message"
aria-describedby="basic-addon2"
id="text"
value={text}
name="text"
onChange={onChange}
/>
</div>
<div className="col-2">
<button className="btn btn-outline-secondary" type="submit">
Send
</button>
</div>
</form>
</div>
);
};
const mapDispatchToProps = (dispatch) => ({
addMessages: (text, roomId) => dispatch(addMessages(text, roomId)),
getMessages: (roomId) => dispatch(getMessages(roomId)),
deleteMessages: (id) => dispatch(deleteMessages(id)),
});
const mapStateToProps = (state, props) => ({
messages: state.messages,
roomId: props.location.state.roomId,
});
export default connect(mapStateToProps, mapDispatchToProps)(MessageForm);
答案 0 :(得分:1)
有两个问题。
awk 'BEGIN {FS = OFS = "\t"} {for (i=4; i<=12; i+=2) {sub(/./,"&\t",$i)1;} print $0};' file1
,这可能会更新| awk 'BEGIN {FS=OFS="\t"} FNR==NR {a[$1,$2,$5]; next} FNR==1 { next } {for (i=4; i<=12; i+=3) {print $0, (($1,$2,$4) in a ? "ref":"dev"), (($1,$2,$i + 1 ) in a ? "ref":"dev")}}' file2 -
的方法都是props,如果更改,则整个组件都会更新。 useEffect不能控制父组件,因此,每次父组件更新时,子组件也会进行控制。getMessages
中调用一个方法,该方法将重新加载messages
,然后它将再次调用useEffect
。我可以通过将messages
移出该组件来解决此问题,或者将if语句放入useEffect
中以查看是否需要调用getMessages
。
答案 1 :(得分:0)
除了@nzajt的答案外,也许您不需要使用“消息”作为对useEffect的依赖。只需将其视为componentDidMount
useEffect(() => {
getMessages(roomId);
scrollToBottom();
}, []);
这样,它不会无限期地重新渲染,但是在第一个渲染之后您将不再获得任何更新。 如果您要实时查找某些内容,请使用websocket查看一些内容,设置侦听器,或者使getMessages函数每隔几秒钟运行一次。