チャットしようとしています。しかし、メッセージを送信するときは、ページのデータを取得するためにページを更新する必要があります。FormsとSendMsgをコンポーネント化する必要があります。
親:
...
import client from '../Utils/Contentful';
export default class Forms extends Component {
constructor() {
super()
this.state = {
messages: [],
}
}
componentDidMount(){
client.getEntries({limit:300, order: 'sys.createdAt', content_type:'nameTest'}).then(response => {
this.setState({messages: response.items});
}).catch(e => {
console.log(e);
});
}
render() {
return (
<div className="chat">
<div className="container-xl">
<MessageList messages={this.state.messages}/>
<SendMsg />
</div>
</div>
);
}
}
そして子コンポーネント
...
import client from '../Utils/ContentfulCM';
export default class SendMsg extends Component {
constructor() {
super()
this.state = {
message:'',
userEmail:'[email protected]',
chatName:'ggg'
}
this.sendMessage = this.sendMessage.bind(this)
this.handleChange = this.handleChange.bind(this)
}
handleChange(e) {
this.setState({
message: e.target.value,
})
}
sendMessage(e) {
e.preventDefault();
const form = e.target;
const data = new FormData(form);
client.getSpace(client.space)
.then((space) => space.getEnvironment('master'))
.then((environment) => environment.createEntry('nameTest', {
fields: {
chatName: {
'en-US': data.get('chatName')
},
//... some data
}
}))
.then((entry) => entry.publish())
.catch(console.error)
this.setState({
message: ''
})
}
render() {
return (
<div className="send-message">
<Form className="send-msg" onSubmit={this.sendMessage}>
<FormGroup>
<Input type="hidden" name="userEmail" value={this.state.userEmail}/>
</FormGroup>
<FormGroup>
<Input type="hidden" name="chatName" value={this.state.chatName}/>
</FormGroup>
<FormGroup>
<Input
type="text"
name="text"
onChange={this.handleChange}
value={this.state.message}
placeholder="Write your message here"
required />
</FormGroup>
<FormGroup>
<Input type="hidden" name="dateCreated" value={moment().format()} onChange={this.handleChange}/>
</FormGroup>
</Form>
</div>
);
}
}
小道具を追加しようとしましたが、適切な場所がわかりません。何か提案はありますか?
両方のコンポーネントに「インポートクライアント」があり(uniq accessTokenがあるため、これらは異なります)、そのため、1つのコンポーネントでそれらを使用することはできません。
以下の提案に従って質問を変更しましたが、表示されたデータを取得するにはページを更新する必要があります。
親:
export default class Forms extends Component {
constructor() {
super()
this.state = {
messages: [],
}
this.sendMessage = this.sendMessage.bind(this);
}
componentDidMount(){
client1.getEntries({limit:300, order: 'sys.createdAt', content_type:'nameTest'}).then(response => {
this.setState({messages: response.items});
}).catch(e => {
console.log(e);
});
}
sendMessage(data) {
client2.getSpace(client2.space)
.then((space) => space.getEnvironment('master'))
.then((environment) => environment.createEntry('nameTest', {
fields: {
chatName: {
'en-US': data.get('chatName')
... some data
}
}))
.then((entry) => entry.publish())
.catch(console.error)
}
render() {
return (
<div className="chat">
<div className="container-xl">
<MessageList messages={this.state.messages}/>
<SendMsg onSendMessage={this.sendMessage}/>
</div>
</div>
);
}
}
そして子コンポーネント
export default class SendMsg extends Component {
constructor() {
super()
this.state = {
message:'',
userEmail:'[email protected]',
chatName:'ggg'
}
this.sendMessage = this.sendMessage.bind(this)
this.handleChange = this.handleChange.bind(this)
}
handleChange(e) {
this.setState({
message: e.target.value,
})
}
sendMessage(e) {
e.preventDefault();
const { onSendMessage } = this.props;
const form = e.target;
const data = new FormData(form);
// if send message handler was passed, invoke with form data
onSendMessage && onSendMessage(data);
this.setState({
message: ''
})
}
render() {
return (
<div className="send-message">
<Form className="send-msg" onSubmit={this.sendMessage}>
<FormGroup>
<Input type="hidden" name="userEmail" value={this.state.userEmail}/>
</FormGroup>
<FormGroup>
<Input type="hidden" name="chatName" value={this.state.chatName}/>
</FormGroup>
<FormGroup>
<Input
type="text"
name="text"
onChange={this.handleChange}
value={this.state.message}
placeholder="Write your message here"
required />
</FormGroup>
<FormGroup>
<Input type="hidden" name="dateCreated" value={moment().format()} onChange={this.handleChange}/>
</FormGroup>
</Form>
</div>
);
}
}
親でコールバックを定義します。子のフォームからメッセージデータを抽出して送信するロジックを分割します。親のコールバックはメッセージデータを受信して送信し、子コンポーネントの関数はフォームデータをプルしてフォーマットし、propsで渡されたコールバックを呼び出し、入力フィールドをクリアします。
親
export default class Forms extends Component {
constructor() {
super()
this.state = {
messages: [],
}
this.sendMessage = this.sendMessage.bind(this);
}
componentDidMount(){
client.getEntries({limit:300, order: 'sys.createdAt', content_type:'nameTest'}).then(response => {
this.setState({messages: response.items});
}).catch(e => {
console.log(e);
});
}
sendMessage(data) {
client.getSpace(client.space)
.then((space) => space.getEnvironment('master'))
.then((environment) => environment.createEntry('nameTest', {
fields: {
chatName: {
'en-US': data.get('chatName')
},
//... some data
}
}))
.then((entry) => entry.publish())
.catch(console.error);
}
render() {
return (
<div className="chat">
<div className="container-xl">
<MessageList messages={this.state.messages}/>
<SendMsg onSendMessage={sendMessage} />
</div>
</div>
);
}
}
子
export default class SendMsg extends Component {
constructor() {
super()
this.state = {
message:'',
userEmail:'[email protected]',
chatName:'ggg'
}
this.sendMessage = this.sendMessage.bind(this)
this.handleChange = this.handleChange.bind(this)
}
handleChange(e) {
this.setState({
message: e.target.value,
})
}
sendMessage(e) {
e.preventDefault();
const { onSendMessage } = this.props;
const form = e.target;
const data = new FormData(form);
// if send message handler was passed, invoke with form data
onSendMessage && onSendMessage(data);
this.setState({
message: ''
});
}
render() {
return (
<div className="send-message">
<Form className="send-msg" onSubmit={this.sendMessage}>
<FormGroup>
<Input type="hidden" name="userEmail" value={this.state.userEmail}/>
</FormGroup>
<FormGroup>
<Input type="hidden" name="chatName" value={this.state.chatName}/>
</FormGroup>
<FormGroup>
<Input
type="text"
name="text"
onChange={this.handleChange}
value={this.state.message}
placeholder="Write your message here"
required />
</FormGroup>
<FormGroup>
<Input type="hidden" name="dateCreated" value={moment().format()} onChange={this.handleChange}/>
</FormGroup>
</Form>
</div>
);
}
}
同期機能を含むように更新
同期API
Javascirptでの同期APIの使用
親コンポーネントの更新:
componentDidMount
コンポーネントのマウント時に初期データを同期するように更新し、データ同期ポーリングを設定します(これはイベント駆動型ではないため)componentWillUnmount
ライフサイクル機能にタイマークリーンアップを追加親
constructor() {
super()
this.state = {
messages: [],
}
this.syncTimer = null;
this.sendMessage = this.sendMessage.bind(this);
}
initialSyncClient = () => client1.sync({
initial: true
limit:100,
order: 'sys.createdAt',
content_type: 'nameTest',
});
syncClient = () => {
const { nextSyncToken } = this.state;
client1.sync({
nextSyncToken
})
.then(this.handleSyncResponse)
.catch(e => {
console.log(e);
});
};
handleSyncResponse = ({ entries, nextSyncToken}) => {
// response shape is a little different,
// response.entries vs. response.items, so need to access correctly
// also need to save nextSyncToken for all subsequent syncs
this.setState({
messages: entries.items,
nextSyncToken,
});
};
componentDidMount(){
// do initial sync
this.initialSyncClient()
.then(this.handleSyncResponse)
.catch(e => {
console.log(e);
});
// setup sync polling, 15 second interval
this.syncTimer = setInterval(syncClient, 15 * 1000);
}
componentWillUnmount() {
// clean up polling timer when component unmounts
clearInterval(this.syncTimer);
}
注:これらの変更は純粋にcontentful
ドキュメントに基づいているため、期待どおりに機能させるために、または矢印関数などを使用したくない場合は、微調整が必要になる場合があります...
関数sendMessageを親に追加しようとしている場所がわかりません。
小道具で提供できますが、そうではありません。
子コンポーネントでは、次のようなことができます
interface IChildComponentWithSendMessage{
sendMessage
}
export class ChildComponent extends React.Component<IChildComponentWithSendMessage>
そしてあなたは小道具によってあなたにmessageMethodを提供することができます
また、あなたはする必要はありません
this.sendMessage = this.sendMessage.bind(this)
また、このメソッドを子/親コンポーネントに提供できない理由が問題になる可能性があると思います
次のような関数を作成できます。
sendMessage = () => {
}
Reba McEntire が息子の Shelby Blackstock と共有しているクリスマスの伝統について学びましょう。
メーガン・マークルとマライア・キャリーが自然な髪の上でどのように結合したかについて、メーガンの「アーキタイプ」ポッドキャストのエピソードで学びましょう.
ハリー王子が家族、特にチャールズ王とウィリアム王子との関係について望んでいると主張したある情報源を発見してください。
ワイノナ・ジャッドが、母親のナオミ・ジャッドが亡くなってから初めての感謝祭のお祝いを主催しているときに、彼女が今では家長であることをどのように認識したかを学びましょう.
Air travel is far more than getting from point A to point B safely. How much do you know about the million little details that go into flying on airplanes?
The world is a huge place, yet some GeoGuessr players know locations in mere seconds. Are you one of GeoGuessr's gifted elite? Take our quiz to find out!
AppleがiOS9を発表したときの大きな話題の1つは、Siriがどのように改善され、より「プロアクティブ」になるかということでした。最初はそれが何を意味するのか実際にはわかりませんでしたが、iOSが1週間使用されたので、iOSに何を依頼できるかについてはるかに良いアイデアが得られました。
非常に多くのサービスと生活費には、たまにしか変わらない設定価格があります。ただし、食料品の請求書は、閉じ込められておらず、完全に管理できる唯一の場所の1つです。
Destinyにとって興味深い週末でした。新しいエクスプロイトのおかげで、プレイヤーはゲームの戦利品システムがどのように機能するかを通常よりも詳しく見ることができました。
今日Destinyをプレイし始めた場合、同じ古代の低レベルのミッションを実行している友人の数が異常に多いことに気付いたかもしれません。なぜ彼らはそうするのでしょうか?答えは-もちろんこれが答えです-ミッションはプレイヤーが新しい抜け穴を利用し、最小限の労力でたくさんの強力なエキゾチックなアイテムを獲得できるようにすることです。
何千人もの Amazon の買い物客が Bedsure Duvet Cover を推奨しており、現在セール中です。羽毛布団カバーにはいくつかの色があり、ツインからカリフォルニアキングまでのサイズがあります。Amazon で最大 52% オフの最高評価の羽毛布団カバーを購入する
BodyRestore ユーカリ シャワー スチーマーは、Amazon で 11,000 を超える 5 つ星の評価を得ています。セルフケアが必要な人へのバレンタインデーのギフトとして、ホームスパ製品を贈りましょう。
多くのAmazonの買い物客がUmlo H6ハンドヘルド掃除機を推奨しており、現在スーパーセール中です. ハンドヘルド デバイスには HEPA フィルターが装備されており、複数のアタッチメントが付属しています。Amazonで75%オフのときにハンドヘルド掃除機を購入する
オクタヴィア・スペンサーは、ヘルプで一緒に共演するずっと前に、シシー・スペイセク主演の 1990 年の映画「ロング・ウォーク・ホーム」でインターンとして働いていました。
人々にチャンスを与えることは、人生で少し遅すぎると私は信じています。寛大に。