2017-06-14 67 views
0

我創建了一個非常簡單的yes/no組件映射到與真正/錯誤的值與redux形式。 單擊「否」時,商店中的值會更新,但組件不會更新。 只有點擊是後,組件纔會更新點擊編號還原窗體組件不反映存儲狀態

我在這裏做錯了什麼?爲什麼商店中的狀態沒有反映在組件中?
請注意,對於我的用例來說非常重要的是,最初沒有單擊按鈕。

沙箱:

https://codesandbox.io/s/r06VKjB4K

import React from 'react'; 
import { Field, reduxForm } from 'redux-form'; 

const buttonStyle = { 
    width: '50px', 
    display: 'inline-block', 
    border: '1px solid green', 
    margin: '5px', 
    padding: '5px', 
    cursor: 'pointer', 
    textAlign: 'center', 
}; 

const ButtonBar = ({ options, input }) => 
    <div style={{ display: 'block' }}> 
    {options.map(x => 
     <div 
     onClick={() => { 
      input.onChange(x.value); 
     }} 
     style={{ 
      ...buttonStyle, 
      ...{ 
      backgroundColor: input.value === x.value ? x.selected : 'white', 
      }, 
     }} 
     > 
     {x.displayName} 
     </div>, 
    )} 
    </div>; 

const SimpleForm = props => { 
    return (
    <form> 
     <div style={{ display: 'inline-block', border: '1px solid grey' }}> 
     <Field 
      name="myButton" 
      component={ButtonBar} 
      options={[ 
      { 
       value: true, 
       displayName: 'Yes', 
       selected: 'green', 
      }, 
      { 
       value: false, 
       displayName: 'No', 
       selected: 'red', 
      }, 
      ]} 
     /> 
     </div> 
    </form> 
); 
}; 

export default reduxForm({ 
    form: 'simple', // a unique identifier for this form 
})(SimpleForm); 
+0

你能不能保持像這樣 input.value == x.value ? – VivekN

+0

@VivekN不,我在問題中指出爲什麼不是 –

+0

確實與「真/假」值有關。如果用「a」和「b」代替它,它會按預期工作。我對redux形式不是很熟悉,但文檔可能會解釋這一點。 – enapupe

回答

1

我認爲原因是在redux形式的代碼中,它將空字符串和false視爲最初的相同事物,並且不會觸發重新渲染。它看起來像終極版形式使用該deepEquals功能定製:

const customizer = (obj, other) => { 
    if (obj === other) return true 
    if (
    (obj == null || obj === '' || obj === false) && 
    (other == null || other === '' || other === false) 
) 
    return true 

    if (obj && other && obj._error !== other._error) return false 
    if (obj && other && obj._warning !== other._warning) return false 
} 

你可以嘗試的初始值設置爲false自己,看看是否能解決您的問題。

+0

接受這個答案,因爲這實際上直接指向了代碼形式爲6的代碼。它將以redux-form 7的形式修復(希望 - > https://github.com/erikras/redux-form/pull/3081) –

2

IDK你Redux的形式是如何工作的,但有關於未定義的初始狀態和錯誤值的一些問題; 使用format你能處理

https://codesandbox.io/s/BL50OzNZY

 format={(value) => value} 

剛剛返回值,沒有必要額外的檢查。

+1

這很好奇,因爲你的函數從字面上看不會做任何事情。 這似乎是添加一個格式化程序本身的行爲有修復問題的副作用。 –

+0

沒錯。對於那個IF,沒有必要,只是返回值本身就會覆蓋排除你的虛假價值的其他驗證。 – enapupe

+0

好了,但現在每個使用我的組件的人都需要包含一個不做任何事情的神祕格式化程序。不愉快的解決方案。 –

1

這是因爲你的Field「myButton」的初始狀態等於「」,並且當你點擊「No」按鈕時,狀態改變爲false,但是由於新狀態等於前一個狀態(「」==假)組件不重新呈現。

你可以解決這個問題,爲你的組件傳遞一些初始狀態,它與你的選項(true和false)不同。例如,你可以設置初始狀態爲任意字符串:

<SimpleForm 
    initialValues={{ myButton: 'notTrueOrFalse' }} 
    onSubmit={showResults} 
    /> 

https://codesandbox.io/s/0R1rw63nV

+0

用'notTrueOrFalse'初始化了商店,我相信這並不理想。 – enapupe

+0

我很欣賞那個作品,但它似乎不是一個很好的解決方案。 除了初始化表單之外,在提交表單時,我必須添加額外的邏輯來刪除無用的值。我只想保持一個布爾值。 –

+0

@ WillemD'Haeseleer我相信你已經需要添加一些額外的邏輯,因爲你的組件可以給你三個可能的值:true,false,「」。 默認情況下,將組件的初始值設置爲true或false可能是有意義的。 –