Передайте опору redux

У меня такой код:

main.js

submit(v) {
    console.info(v);
    const price = v.get("price");
  }

render() {  
<form onSubmit = {handleSubmit(this.submit)}>
    <Field
    name = "products"
    categoryId = {categoryId}
    component = {MyComponent}
    />

    <MySubmitComponent
    confirm = {handleSubmit(this.submit)}
    />
  </form>
}

MyComponent.js

{this.props.products.map((product, index) => (
<ProductDetails
productId = {product.productId}
price = {product.price}
/>
))}

ProductsDetails.js

    <Field
    name = "price"
    price = {price}
    component = {PriceText}
    initialValues
    />

    const selector = formValueSelector("products");
    const mapStateToProps = (state, ownProps) => {
      return {
        initialValues: { productId: ownProps.productId },
        productId: selector(state, "productId")
      };
    };
    ProductsDetails= connect(mapStateToProps)(ProductsDetails);

Когда я меняю цену продукта и нажимаю кнопку «Отправить», значения переменных в функции отправки содержат только новая цена товара без его productId. Мне также нужен productId, чтобы сообщить о соответствующем продукте. Что я скучаю?

Где вы храните products и как обновляете цену?

huMpty duMpty 15.10.2018 14:11

@huMptyduMpty Я веду продукты в базе данных и обновляю цену, щелкая по текстовому полю. Это совершенно несущественно, поскольку меня больше всего беспокоит то, что в Поле, где у меня может быть только одно имя с одним значением, я хочу иметь другую опору, которая будет стабильной и не меняется. Это productId. Прямо сейчас, когда я меняю цену продукта и нажимаю кнопку «Отправить», я беру только новую цену без ее productId. Но без productId я не могу справиться с новой ценой дальше. Можно ли передать productId как неизменяемую опору в поле?

Kathrine Hanson 16.10.2018 09:30
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
2
2
125
2

Ответы 2

Насколько я знаю и использовал redux-form, один компонент Field будет иметь только одно значение, зарегистрированное в Store.

Таким образом, вы можете подойти к нему как к нескольким различным формам, где каждая форма будет иметь отдельные поля productId и price. После отправки формы у вас будут значения обоих полей.

Вот пример создания нескольких форм.

В соответствии с вашим вариантом использования это будет примерно так:

Использование:

{ this.props.products.map(({ productId, price }, index) => (
  <Form form = {`product-${productId}`} initialValues = {{ productId, price }} />
/>
))}

<Form />:

const Form = reduxForm({
  // no need to put form again here as we are sending form props.
})(FormComponent);

<FormComponent /> - просто презентационная составляющая:

export const FormComponent = ({ handleSubmit }) => <form onSubmit = {handleSubmit}>
  <Field
    name = "price"
    component = {PriceText}
  />
</form>

Но я не хочу обновлять procuctId. Я просто хочу передать его вместе с priceId. PriceId можно изменить, но procuctId - нет.

Kathrine Hanson 15.10.2018 14:19

Ага. Это было бы скрытое Поле. Только что зарегистрировались в Форме. Делая это таким образом - productId не может быть обновлен, но оба поля будут доступны при отправке формы.

Jordan Enev 15.10.2018 14:20

<Field component = "input" type = "text" placeholder = {productId} name = "productId" /> Это не работает. Мне нужно изменить содержимое, чтобы увидеть значение, когда я нажимаю кнопку «Отправить». :-(

Kathrine Hanson 15.10.2018 14:36

Просто добавьте type='hidden'.

Jordan Enev 15.10.2018 14:38

Это просто скрывает компонент. Это ничего не меняет.

Kathrine Hanson 15.10.2018 14:40

О, да. Для всех форм вы должны зарегистрировать initialValues, где вам нужно будет установить значение productId по умолчанию. При этом вам не нужно будет отображать скрытое поле.

Jordan Enev 15.10.2018 14:42

Вы можете разделить форму как отдельный компонент и передать ей productId в качестве реквизита. Имея опору productId, вы можете динамически создавать имя формы и также установить для него значение initialValues. Что-то подобное.

Jordan Enev 15.10.2018 14:45

@KathrineHanson Я добавил к ответу полный пример. Надеюсь, он направит и поможет вам.

Jordan Enev 15.10.2018 15:13

Большое спасибо. Это отличается от моего подхода, но ваш пример очень хорош!

Kathrine Hanson 15.10.2018 15:45

Пожалуйста. Если ответ вам чем-то помог, вы можете принять / проголосовать за него. Спасибо :)

Jordan Enev 15.10.2018 15:51

Я отредактировал свой образец кода. Как видите, только в main.js я использую форму и объявляю свою функцию отправки. Я хочу остаться как есть и не делать другую форму в дочернем компоненте.

Kathrine Hanson 16.10.2018 09:15

Хорошо. Если вы найдете другое решение, я был бы рад увидеть ваш подход в качестве ответа.

Jordan Enev 16.10.2018 10:16

Привет. Я сделал smt более простым по конструкции, но теперь я столкнулся с этой проблемой. Я хочу показать несколько товаров. Когда вы нажимаете кнопку, вызывается goForward (), и вы можете увидеть следующий продукт. Моя проблема в том, что когда вызывается submit (), переменная значений не содержит текущий productId отображаемого продукта. Вместо этого отображается неопределенное. Проблема не только в неопределенном значении, но и в том, что productId имеет свое начальное значение. Что случилось?

Kathrine Hanson 17.10.2018 11:11

Странно то, что console.info в реквизитах карты вызывается в начале один раз и показывает текущий productId.

Kathrine Hanson 17.10.2018 11:13
class MyComponent extends Component {
  constructor(props) {
    super(props);
    this.state = {
        activeIndex: 0
    };
    this.submit = this.submit.bind(this);
    this.goForward= this.goForward.bind(this);
  }

  submit(values) {
    console.info(values);
  }

  goForward() {
    let index = this.state.activeIndex;
    let productsSize = products.length - 1;

    if (index === productsSize) {
      index = -1;
    }

    ++index;

    this.setState({
      activeIndex: index
    });
  }

  render() {
      <form onSubmit = {handleSubmit(this.submit)} name = "edit">
          {this.props.products.map((product, index) => (
          <ProductDetails
          productId = {product.productId}
          price = {product.price}
          />
          ))}
    </form>
  }


let MyProductComponent = reduxForm({ form: "edit" })(
  MyComponent
);

const mapStateToProps = (state, ownProps) => {
  console.info(formValueSelector("edit")(
        state,
        "activeIndex");
  return {
    initialValues: {
      productId: formValueSelector("edit")(
        state,
        "activeIndex"
      )
    }
  };
};

MyProductComponent = withRouter(
  connect(mapStateToProps)(toJS(MyProductComponent))
);

Пожалуйста, добавьте детали / документацию, что вы делаете.

Jordan Enev 17.10.2018 11:33

Я показываю детали некоторых продуктов, такие как цена, размер, цвет и т. д. Каждый продукт отображается, когда вы нажимаете кнопку «Далее», где вызывается goForward (). Вы также можете изменить цену продукта, и есть кнопка «Отправить». Моя проблема в том, что когда я нажимаю «Далее», чтобы увидеть другой продукт, productId не получает текущего значения. Он содержит начальное значение, которое является productId первого продукта (this.state = {activeIndex: 0};). Функция setState внутри goForward () работает. Но почему я все еще получаю начальное значение?

Kathrine Hanson 17.10.2018 12:03

Параметр enableReinitialize очень помог с undefinied, но состояние не меняется.

Kathrine Hanson 17.10.2018 12:04

Я не уверен, что правильно понимаю проблему, но это возможность обновить текущий продукт с помощью redux-formchange action creator` методом goForward. Вот пример: stackoverflow.com/questions/45230531/… Однако я бы порекомендовал вам открыть новый подробный вопрос, связанный только с этой проблемой, потому что он не имеет отношения к текущим деталям вопроса. Пожалуйста, предоставьте полную информацию.

Jordan Enev 17.10.2018 12:47

Кроме того, если вы сделаете это так, как я упоминал в своем ответе, пара продукта и цены будет организована в единой форме, и у вас не будет такой проблемы. Пожалуйста, попытайтесь понять мой ответ и попробуйте.

Jordan Enev 17.10.2018 12:55

Другие вопросы по теме