programing

반응 입력 defaultValue가 상태와 함께 업데이트되지 않음

minimums 2023. 2. 22. 21:40
반응형

반응 입력 defaultValue가 상태와 함께 업데이트되지 않음

react를 사용하여 간단한 폼을 작성하려고 하는데 데이터가 폼의 defaultValue에 올바르게 바인딩되는 데 어려움이 있습니다.

제가 찾고 있는 동작은 다음과 같습니다.

  1. 페이지를 열면 텍스트 입력 필드에 데이터베이스에 있는 부재중 메시지의 텍스트가 입력되어야 합니다.즉, "샘플 텍스트"입니다.
  2. 데이터베이스의 AwayMessage에 텍스트가 없는 경우 텍스트 입력 필드에 플레이스홀더를 설정하는 것이 좋습니다.

그러나 지금은 페이지를 새로 고칠 때마다 텍스트 입력 필드가 비어 있습니다.(단, 입력에 입력한 내용은 올바르게 저장되며 지속됩니다.)이것은 입력 텍스트 필드의 html이 Away Message가 빈 오브젝트일 경우 로딩되지만 away Message가 로딩되어도 새로고침되지 않기 때문이라고 생각합니다.또한 필드에 기본값을 지정할 수 없습니다.

알기 쉽게 하기 위해 일부 코드를 삭제했습니다(on Toggle Change).

    window.Pages ||= {}

    Pages.AwayMessages = React.createClass

      getInitialState: ->
        App.API.fetchAwayMessage (data) =>
        @setState awayMessage:data.away_message
        {awayMessage: {}}

      onTextChange: (event) ->
        console.log "VALUE", event.target.value

      onSubmit: (e) ->
        window.a = @
        e.preventDefault()
        awayMessage = {}
        awayMessage["master_toggle"]=@refs["master_toggle"].getDOMNode().checked
        console.log "value of text", @refs["text"].getDOMNode().value
        awayMessage["text"]=@refs["text"].getDOMNode().value
        @awayMessage(awayMessage)

      awayMessage: (awayMessage)->
        console.log "I'm saving", awayMessage
        App.API.saveAwayMessage awayMessage, (data) =>
          if data.status == 'ok'
            App.modal.closeModal()
            notificationActions.notify("Away Message saved.")
            @setState awayMessage:awayMessage

      render: ->
        console.log "AWAY_MESSAGE", this.state.awayMessage
        awayMessageText = if this.state.awayMessage then this.state.awayMessage.text else "Placeholder Text"
        `<div className="away-messages">
           <div className="header">
             <h4>Away Messages</h4>
           </div>
           <div className="content">
             <div className="input-group">
               <label for="master_toggle">On?</label>
               <input ref="master_toggle" type="checkbox" onChange={this.onToggleChange} defaultChecked={this.state.awayMessage.master_toggle} />
             </div>
             <div className="input-group">
               <label for="text">Text</label>
               <input ref="text" onChange={this.onTextChange} defaultValue={awayMessageText} />
             </div>
           </div>
           <div className="footer">
             <button className="button2" onClick={this.close}>Close</button>
             <button className="button1" onClick={this.onSubmit}>Save</button>
           </div>
         </div>

my console.log for Away Message에는 다음이 표시됩니다.

AWAY_MESSAGE Object {}
AWAY_MESSAGE Object {id: 1, company_id: 1, text: "Sample Text", master_toggle: false}

또 다른 으로는 '고치다'를 방법이 .key의 입력입니다.

<input ref="text" key={this.state.awayMessage ? 'notLoadedYet' : 'loaded'} onChange={this.onTextChange} defaultValue={awayMessageText} />

업데이트: 이 경우 투표가 시작되므로, 이 경우 적절한 정보를 얻을 수 있어야 합니다.disabled ★★★★★★★★★★★★★★★★★」readonly콘텐츠를 로드하는 동안 프로포트가 제공되므로 ux 익스피리언스가 저하되지 않습니다.

네, 해킹일 가능성이 높지만 일을 해낼 수 있습니다;-)

defaultValue는 초기 로드 전용입니다.

입력을 초기화하려면 defaultValue를 사용해야 하지만 상태를 사용하여 값을 변경하려면 값을 사용해야 합니다.개인적으로는 초기화를 할 때 default Value를 사용한 후 refs를 사용하여 값을 제출하는 것을 좋아합니다.레퍼런스 및 입력에 대한 자세한 내용은 리액트 문서(https://facebook.github.io/react/docs/forms.html 및 https://facebook.github.io/react/docs/working-with-the-browser.html)를 참조하십시오.

입력 내용을 다시 쓰는 방법은 다음과 같습니다.

awayMessageText = if this.state.awayMessage then this.state.awayMessage.text else ''
<input ref="text" onChange={this.onTextChange} placeholder="Placeholder Text" value={@state.awayMessageText} />

또한 플레이스홀더 텍스트를 전달하면 실제로 값이 '플레이스홀더 텍스트'로 설정되기 때문에 이전처럼 플레이스홀더 텍스트를 전달하지 않습니다.undefined 및 nero 값은 기본적으로 defaultValue로 바뀌기 때문에 입력에 공백 값을 전달할 필요가 있습니다.https://facebook.github.io/react/tips/controlled-input-null-value.html 를 참조해 주세요.

getInitialState가 API 호출을 할 수 없습니다.

getInitialState 실행 후 API 호출이 필요합니다.당신의 경우 componentDidMount로 하겠습니다.https://facebook.github.io/react/tips/initial-ajax.html 의 예를 따릅니다.

컴포넌트의 라이프 사이클에 대해 리액션과 함께 읽어보는 것도 추천합니다.https://facebook.github.io/react/docs/component-specs.html 를 참조해 주세요.

수정 및 로드 상태를 사용하여 다시 쓰기

개인적으로 저는 전체 작업을 하고 싶지 않습니다. 만약 그 이외의 경우 렌더 내의 로직을 사용하고, 제 상태에서 "loading"을 사용하여 폼이 로드되기 전에 글꼴을 멋진 스피너로 렌더링하는 것을 선호합니다. http://fortawesome.github.io/Font-Awesome/examples/.http://fortawesome.github.io/Font-Awesome/examples/내가 무슨 말을 하는지 보여 주기 위해 다시 써줄게.제가 cjsx의 진드기를 망쳤다면 제가 원래 이렇게 커피스크립트를 쓰거든요.

window.Pages ||= {}

Pages.AwayMessages = React.createClass

  getInitialState: ->
    { loading: true, awayMessage: {} }

  componentDidMount: ->
    App.API.fetchAwayMessage (data) =>
      @setState awayMessage:data.away_message, loading: false

  onToggleCheckbox: (event)->
    @state.awayMessage.master_toggle = event.target.checked
    @setState(awayMessage: @state.awayMessage)

  onTextChange: (event) ->
    @state.awayMessage.text = event.target.value
    @setState(awayMessage: @state.awayMessage)

  onSubmit: (e) ->
    # Not sure what this is for. I'd be careful using globals like this
    window.a = @
    @submitAwayMessage(@state.awayMessage)

  submitAwayMessage: (awayMessage)->
    console.log "I'm saving", awayMessage
    App.API.saveAwayMessage awayMessage, (data) =>
      if data.status == 'ok'
        App.modal.closeModal()
        notificationActions.notify("Away Message saved.")
        @setState awayMessage:awayMessage

  render: ->
    if this.state.loading
      `<i className="fa fa-spinner fa-spin"></i>`
    else
    `<div className="away-messages">
       <div className="header">
         <h4>Away Messages</h4>
       </div>
       <div className="content">
         <div className="input-group">
           <label for="master_toggle">On?</label>
           <input type="checkbox" onChange={this.onToggleCheckbox} checked={this.state.awayMessage.master_toggle} />
         </div>
         <div className="input-group">
           <label for="text">Text</label>
           <input ref="text" onChange={this.onTextChange} value={this.state.awayMessage.text} />
         </div>
       </div>
       <div className="footer">
         <button className="button2" onClick={this.close}>Close</button>
         <button className="button1" onClick={this.onSubmit}>Save</button>
       </div>
     </div>

그 정도면 충분할 겁니다.이것이 상태와 가치를 사용하는 형태에 대한 한 가지 방법입니다.값 대신 defaultValue를 사용한 다음 refs를 사용하여 전송 시 값을 가져올 수도 있습니다.이 경로를 사용할 경우 데이터를 가져와 폼에 전달하기 위한 외부 셸 컴포넌트(일반적으로 상위 컴포넌트라고 함)를 사용하는 것이 좋습니다.

전체적으로 리액션 문서를 읽고 튜토리얼을 실행하는 것이 좋습니다.많은 블로그가 있고 http://www.egghead.io에는 좋은 튜토리얼이 있습니다.제 사이트 http://www.openmindedinnovations.com에도 몇 가지 정보가 있습니다.

매우 간단합니다. defaultValue와 키를 동일하게 설정합니다.

<input defaultValue={myVal} key={myVal}/>

이는 https://reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html#recommendation-fully-uncontrolled-component-with-a-key에서 권장되는 접근법 중 하나입니다.

defaultValue를 강제로 다시 렌더링하려면 입력 자체의 키 값을 변경하기만 하면 됩니다.방법은 다음과 같습니다.

<input 
type="text" 
key={myDynamicKey} 
defaultValue={myDynamicDefaultValue} 
placeholder="It works"/>

최선의 해결책은 아닐지 모르지만, 코드 내 모든 곳에서 재사용할 수 있도록 다음과 같은 컴포넌트를 만들겠습니다.디폴트로 이미 리액션이 되어 있으면 좋을 텐데.

<MagicInput type="text" binding={[this, 'awayMessage.text']} />

컴포넌트는 다음과 같습니다.

window.MagicInput = React.createClass

  onChange: (e) ->
    state = @props.binding[0].state
    changeByArray state, @path(), e.target.value
    @props.binding[0].setState state

  path: ->
    @props.binding[1].split('.')
  getValue: ->
    value = @props.binding[0].state
    path = @path()
    i = 0
    while i < path.length
      value = value[path[i]]
      i++
    value

  render: ->
    type = if @props.type then @props.type else 'input'
    parent_state = @props.binding[0]
    `<input
      type={type}
      onChange={this.onChange}
      value={this.getValue()}
    />`

여기서 change by array는 어레이로 표현된 경로로 해시에 액세스하는 함수입니다.

changeByArray = (hash, array, newValue, idx) ->
  idx = if _.isUndefined(idx) then 0 else idx
  if idx == array.length - 1
    hash[array[idx]] = newValue
  else
    changeByArray hash[array[idx]], array, newValue, ++idx 

관련 문제

설정defaulValue제어 중 dinn't update(업데이트 없음)state.

역방향으로 동작하는 것은 완벽합니다.

  • 세트state제어 UI가 올바르게 갱신됩니다.defaulValue주어졌다.

코드:

let defaultRole = "Owner";

const [role, setRole] = useState(defaultRole);

useEffect(() => {
    setMsg(role);
});

const handleChange = (event) => {
    setRole(event.target.value );
};

// ----

<TextField
    label="Enter Role"
    onChange={handleChange}
    autoFocus
    value={role}
/>
  1. 기본값의 상태를 정의합니다.
  2. 입력의 테두리를div및 akey받침대
  3. 키 값을 입력의 defaultValue와 같은 값으로 설정합니다.
  4. 고객님께 전화setDefaultValue스텝 1에서 정의되어 컴포넌트를 재설치할 수 있습니다.

예:

const [defaultValue, setDefaultValue] = useState(initialValue);

useEffect(() => {
    setDefaultValue(initialValue);
}, false)

return (
    <div key={defaultValue}>
        <input defaultValue={defaultValue} />
    </div>
)

매개 변수 "placeHolder"에 값을 지정합니다.예:-

 <input 
    type="text"
    placeHolder="Search product name."
    style={{border:'1px solid #c5c5c5', padding:font*0.005,cursor:'text'}}
    value={this.state.productSearchText}
    onChange={this.handleChangeProductSearchText}
    />

사용하다value대신defaultValue를 사용하여 입력값을 변경합니다.onChange방법.

언급URL : https://stackoverflow.com/questions/30146105/react-input-defaultvalue-doesnt-update-with-state

반응형