我对 React 和构建原型(prototype)聊天应用程序还很陌生。同一页面上有两个窗口,一个是帮助代理,另一个是客户(或请求帮助的人)。当代理或客户输入消息时,该消息应出现在两个窗口中。但是,我当前的版本只在每个窗口中显示关联的用户,而不是在两个窗口中显示消息。还需要保持提交按钮处于非事件状态,直到消息框中有文本为止。
我试过使用 <button type="button" disabled={!this.state.email}>Button</button>
并添加 value={this.state.message} onChange={this.handleChange}
到输入字段,但这已被证明是无效的。
因此,第一件事是如何在任一用户输入消息时让消息显示在两个窗口中。最后,如何正确设置按钮状态?
我的应用程序是这样分解的:
MessageList.js
和 MessageForm.js
是注入(inject) User.js
的组件和 Agent.js
,然后注入(inject) App.js
MessageList.js
class MessageList extends Component {
componentDidUpdate = () => {
this.node.scrollTop = this.node.scrollHeight
}
render() {
return (
<div className="MessageList" ref={(node) => (this.node = node)}>
{this.props.messages.map((message, i) => (
<Message key={i} {...message} />
))}
</div>
)
}
}
export default MessageList
MessageForm.js
class MessageForm extends Component {
static propTypes = {
onMessageSend: PropTypes.func.isRequired,
}
componentDidMount = () => {
this.input.focus()
}
handleFormSubmit = (event) => {
event.preventDefault()
this.props.onMessageSend(this.input.value)
this.input.value = ""
}
render() {
return (
<form className="MessageForm" onSubmit={this.handleFormSubmit}>
<div className="input-container">
<input
type="text"
ref={(node) => (this.input = node)}
placeholder="Enter Message..."
/>
</div>
<div className="button-container">
<button type="submit">
Send
</button>
</div>
</form>
)
}
}
export default MessageForm
User.js
class User extends Component {
constructor(props) {
super(props)
this.state = {
messages: [],
}
}
render() {
return (
<div className="User">
<header>
<p>You</p>
</header>
<MessageList messages={this.state.messages} />
<MessageForm onMessageSend={this.handleNewMessage} />
</div>
);
}
}
export default User;
Agent.js
class Agent extends Component {
constructor(props) {
super(props)
this.state = {
messages: [],
}
}
render() {
return (
<div className="Agent">
<header>
<p>Agent</p>
</header>
<MessageList messages={this.state.messages} />
<MessageForm onMessageSend={this.handleNewMessage} />
</div>
);
}
}
export default Agent;
App.js
class App extends Component {
static propTypes = {
messages: PropTypes.arrayOf(PropTypes.object)
}
static defaultProps = {
messages: [],
}
handleNewMessage = (text) => {
this.setState({
messages: [...this.state.messages, {me: true, author: "Me", body: text}, {me: false, author: "Agent", body: text}]
})
}
render() {
return (
<div className="App">
<div className="agentWindow">
<Agent />
</div>
<div className="userWindow">
<User />
</div>
</div>
);
}
}
export default App;
Message.js
class Message extends Component {
static propTypes = {
author: PropTypes.string,
body: PropTypes.string.isRequired,
me: PropTypes.bool,
}
render() {
const classes = classNames('Message', {
log: !this.props.author,
me: this.props.me
})
return (
<div className={classes}>
{this.props.author && (
<span className="author">{this.props.author}:</span>
)}
{this.props.body}
</div>
)
}
}
export default Message
最佳答案
您的消息没有显示在两个窗口上,因为您在 Agent
和 User
内部创建状态,并且它们是独立的。因此,如果您向一个状态添加一条消息,它不会添加到另一个状态。你可以看看Redux在组件之间共享状态,或者你可以将你的 messages
状态和你的 handleNewMessage
方法放在 App
中并将它们作为 Prop 传递给 Agent
和 User
,这样他们将使用相同的状态。看一看:
App.js
class App extends Component {
constructor(props) {
super(props);
this.state = {
messages: []
}
this.handleNewMessage = this.handleMessage.bind(this);
}
static propTypes = {
messages: PropTypes.arrayOf(PropTypes.object)
}
handleNewMessage = (text) => {
this.setState({
messages: [...this.state.messages, {me: true, author: "Me", body: text}, {me: false, author: "Agent", body: text}]
})
}
render() {
return (
<div className="App">
<div className="agentWindow">
<Agent messages={this.state.messages} handleNewMessage={this.handleNewMessage} />
</div>
<div className="userWindow">
<User messages={this.state.messages} handleNewMessage={this.handleNewMessage} />
</div>
</div>
);
}
}
User.js
class User extends Component {
render() {
return (
<div className="User">
<header>
<p>You</p>
</header>
<MessageList messages={this.props.messages} />
<MessageForm onMessageSend={this.props.handleNewMessage} />
</div>
);
}
}
export default User;
Agent
也是如此。
关于禁用按钮,你可以添加一个受控输入,它看起来像这样:
class ExampleForm extends React.Component {
constructor(props) {
super(props);
this.state = {message: ''};
this.handleChange = this.handleChange.bind(this);
}
handleChange(event) {
this.setState({value: event.target.value});
}
render() {
return (
<form>
<label>
Name:
<input type="text" value={this.state.value} onChange={this.handleChange} />
</label>
<button type="submit" disabled={this.state.message === ''}>Send<button/>
</form>
);
}
}
关于javascript - 使用 React 在两个 div 中显示提交的文本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48846635/