如何在 nextjs 中将对象作为 prop 传递

how to pass an object as a prop in nextjs

我不太明白在 Next JS 中使用 useState 时应该如何将对象作为 prop 传递。

我有一个在 javascript 函数中创建的 lorem ipsum 生成器。我有一个名为 Paragraphs 的组件来容纳它。我需要传入两个属性,

  1. 多个段落。
  2. 一个句子长度。

段落长度由用户输入 1-10 的文本输入设置。句子长度由单选按钮设置。

我 运行 遇到的问题是,当您输入任何值时,setState 会被调用(有意)并且它起作用,问题是它一直在起作用。我只想在单击“冒险”按钮生成数据时更新它。我不确定如何将这些值设置为将它们设置为对象 属性 值然后传递对象。

下面是我的字段代码

import React, { useState } from 'react'


import Paragraph from '../components/ipsum/Paragraph.js'


export default function rpgIpsum() {

    const [paragraphNumber, setParagraphNumber] = useState(5)
    const [sentenceLength, setSentenceLength] = useState(5)
    const [data, setData ] = useState({
        outputProps: {
            paragraphNumber: 5,
            sentenceLength: 5
        }
    })

    return (
        <div>
            {data.outputProps.paragraphNumber}
            <div className="container">
                <div className="row">
                    <div className="col-md-2 d-sm-none d-xs-none d-md-block d-none">
                        {/* <img src="public/images/Bard.jpg" alt="Lorem Ipsum Bard!" className="img-fluid" /> */}
                    </div>
                    <div className="col-md-10">
                        <h2>Looking to add some fun to your filler text?</h2>
                        <h5>Let's Spiffy up your copy with some RPG inspired Lorem Ipsum!</h5>

                        <div className="form-container">
                            <p>First, select how many paragraphs you want.  
                                <input 
                                    type="text" 
                                    name="para" 
                                    value={paragraphNumber} 
                                    className="para-box" 
                                    required 
                                    onInput={
                                        event => setParagraphNumber(parseInt(event.target.value))
                                    }
                                />
                                <small id="para-box-help" className="form-text text-muted">(Max of 10)</small>
                            </p>
                            <p>Next, select the length of the sentences</p>
                            <div className="form-check form-check-inline">
                                <input 
                                    className="form-check-input" 
                                    type="radio" 
                                    name="sentences" 
                                    value="3" 
                                    required 
                                    onInput={
                                        event => setSentenceLength(parseInt(event.target.value))
                                    }
                                /> 
                                <label className="form-check-label" htmlFor="inlineRadio1">Short</label>
                            </div>
                            <div className="form-check form-check-inline">
                                <input 
                                    className="form-check-input" 
                                    type="radio" 
                                    name="sentences" 
                                    value="5" 
                                    required 
                                    onInput={
                                        event => setSentenceLength(parseInt(event.target.value))
                                    }
                                />
                                <label className="form-check-label" htmlFor="inlineRadio2">Medium</label>
                            </div>
                            <div className="form-check form-check-inline">
                                <input 
                                    className="form-check-input" 
                                    type="radio" 
                                    name="sentences" 
                                    value="7" 
                                    required 
                                    onInput={
                                        event => setSentenceLength(parseInt(event.target.value))
                                    }
                                />
                                <label className="form-check-label" htmlFor="inlineRadio3">Long</label>
                            </div>
                            <div className="form-group">
                                <button type="submit" className="btn btn-primary"   
                                    onClick={ event => "what do i do here?" ))}
                                >Adventure!</button>
                            </div>
                        </div>
                    </div>
                </div>
                <div className="row">
                    <div className="col-12">
                        <hr />
                            <Paragraph paragraphNumber={data.outputProps.paragraphNumber} sentenceLength={data.outputProps.sentenceLength}/>
                                                
                    </div>
                </div>
            </div>
        </div>
    )
}

您需要创建一个父组件并将组件的状态提升到该父组件。或者你可以使用 Redux 来管理你的状态,它会让你更容易将数据传递给你的组件。

我要做的是将输入功能重构为一个单独的组件,并使用函数 prop 将输入数据传递给也包含 Paragraph 组件的外部组件,如下所示:

// rpgIpsum.js
export default function rpgIpsum() {
  const [settings, setSettings] = useState({
    paragraphNumber: 5,
    sentenceLength: 5
  });

  return (
    <>
      <ParagraphInput onSubmit={setSettings} />
      <Paragraph {...settings} />
    </>
  );
}

// ParagraphInput.js
export default function ParagraphInput({ onSubmit }) {
  const [paragraphNumber, setParagraphNumber] = useState(5);
  const [sentenceLength, setSentenceLength] = useState(5);

  return (
    <div>
      {/* ... */}
      <button
        type="submit"
        onClick={() => onSubmit({paragraphNumber, sentenceLength})}
      >Adventure!</button>
    </div>
  );
}

这样,rpgIpsum 中的 settings 仅在按下 ParagraphInput 中的按钮时更新,而不是在每次输入更改时更新。