为了账号安全,请及时绑定邮箱和手机立即绑定

React - 在两个现有组件之间渲染组件

React - 在两个现有组件之间渲染组件

翻过高山走不出你 2022-08-18 15:46:00
我对使用React很陌生,我试图构建的是一个动态表单,用户可以在其中添加/删除字段,在添加行(字段)后渲染时出现问题这是我的行组件,我用它作为模板来填充道具class Row extends React.Component {    constructor(props){        super(props);        this.addLine = this.addLine.bind(this)        this.handleTitleChange = this.handleTitleChange.bind(this)        this.handleInquisitionChange = this.handleInquisitionChange.bind(this)    }state = {    pos: this.props.pos,    title: this.props.title,    inquisition: this.props.inquisition}addLine() {     this.props.addLine(this.state.pos);}handleTitleChange = async (event) => {    await this.setState({title: event.target.value});    this.props.updateRowState(this.state.pos, this.state.title, "title")    }handleInquisitionChange = async (event) => {    await this.setState({inquisition: event.target.value});    this.props.updateRowState(this.state.pos, this.state.inquisition, "inquisition")    }render(){  return(    <div className="w3-row odg-line">        <div className="w3-col m2" style={{paddingRight: "8px"}}>            <input type="text" name="titolo[]" placeholder="Argomento" style={{width:"100%"}} onChange={this.handleTitleChange} required/>        </div>        <div className="w3-col m4" style={{paddingRight: "8px"}}>            <textarea form="convocazione" name="istruttoria[]" placeholder="Istruttoria" style={{width:"100%"}} onChange={this.handleInquisitionChange} required></textarea>        </div>        <div className="w3-col m1">            <button type="button" style={{padding:0, height: "24px", width: "24px"}} className="w3-red w3-button w3-hover-white" onClick={() => this.addLine()}>+</button>        </div>    </div>  )}}这是它的父 Convoca,正如你所看到的,每当按下“加号”按钮时,它就会在它之后推动一行并更新组件状态,据我所知,这应该会导致组件再次呈现,但是当它来临时,它只是在已经渲染的按钮之后添加新的addLineclass Convoca extends React.Component {    constructor(props) {        super(props)        this.handleSubmit = this.handleSubmit.bind(this);        this.addLine = this.addLine.bind(this);    }
查看完整描述

1 回答

?
ITMISS

TA贡献1871条经验 获得超8个赞

我会以另一种方式实现功能addLine


请看一下代码段。


const createElement = React.createElement;


class Row extends React.Component {

  render() {

    const {

      position

    } = this.props;


    return createElement('div', null, [

      createElement('input', {

        type: "text",

        value: this.props.title

      }),

      createElement('button', {

        type: "button",

        onClick: () => this.props.onAdd(position)

      }, '+')

    ]);

  }

}



class App extends React.Component {

  constructor(props) {

    super(props);

    this.state = {

      rows: [{

          id: 0,

          position: 0,

          title: 'id 0 position 0'

        },

        {

          id: 1,

          position: 1,

          title: 'id 1 position 1'

        },

      ]

    };


    this.addLine = this.addLine.bind(this);

  }


  addLine(position) {

    const {

      rows

    } = this.state

    const newId = rows.reduce((acc, row) => acc > row.id ? acc : row.id, 0) + 1


    position = position + 1;


    const newRows = [

      ...rows.filter(row => row.position < position),

      {

        id: newId,

        position,

        title: `id ${newId} position ${position}`

      },

      ...rows.filter(row => row.position >= position).map(row => ({ ...row,

        position: row.position + 1,

        title: `id ${row.id} position ${row.position + 1}`

      }))

    ]


    newRows.sort((prev, next) => prev.position - next.position)

    this.setState({

      rows: newRows

    })

  }


  render() {

    const items = this.state.rows.map(item =>

      createElement(Row, {

        key: item.id,

        title: item.title,

        position: item.position,

        onAdd: this.addLine

      })

    )


    return createElement('form', null, items);

  }

}


var rootElement = createElement(App, {}, )


ReactDOM.render(rootElement, document.getElementById('root'))

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>

<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

<div id="root">

</div>

我会以另一种方式实现功能addLine


请看一下代码段。


const createElement = React.createElement;


class Row extends React.Component {

  render() {

    const {

      position

    } = this.props;


    return createElement('div', null, [

      createElement('input', {

        type: "text",

        value: this.props.title

      }),

      createElement('button', {

        type: "button",

        onClick: () => this.props.onAdd(position)

      }, '+')

    ]);

  }

}



class App extends React.Component {

  constructor(props) {

    super(props);

    this.state = {

      rows: [{

          id: 0,

          position: 0,

          title: 'id 0 position 0'

        },

        {

          id: 1,

          position: 1,

          title: 'id 1 position 1'

        },

      ]

    };


    this.addLine = this.addLine.bind(this);

  }


  addLine(position) {

    const {

      rows

    } = this.state

    const newId = rows.reduce((acc, row) => acc > row.id ? acc : row.id, 0) + 1


    position = position + 1;


    const newRows = [

      ...rows.filter(row => row.position < position),

      {

        id: newId,

        position,

        title: `id ${newId} position ${position}`

      },

      ...rows.filter(row => row.position >= position).map(row => ({ ...row,

        position: row.position + 1,

        title: `id ${row.id} position ${row.position + 1}`

      }))

    ]


    newRows.sort((prev, next) => prev.position - next.position)

    this.setState({

      rows: newRows

    })

  }


  render() {

    const items = this.state.rows.map(item =>

      createElement(Row, {

        key: item.id,

        title: item.title,

        position: item.position,

        onAdd: this.addLine

      })

    )


    return createElement('form', null, items);

  }

}


var rootElement = createElement(App, {}, )


ReactDOM.render(rootElement, document.getElementById('root'))

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>

<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

<div id="root">

</div>


查看完整回答
反对 回复 2022-08-18
  • 1 回答
  • 0 关注
  • 99 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信