Как я могу передать значение в переменной компоненту React

#javascript #reactjs #p5.js

#javascript #reactjs #p5.js

Вопрос:

Итак, я использую https://github.com/and-who/react-p5-wrapper для создания p5.js в React.

Мне интересно, есть ли способ передать значение из файла эскиза p5 обратно в React? Например. Я хочу отслеживать значение метки, сгенерированное в p5 Sketch, и использовать его где-нибудь позже. Как я могу сохранить это значение глобально?

 export default function sketch(p5) {

    function modelReady() {
        console.log("Model is ready!!!")
        mobilenet.predict(gotResults)
    }

    function gotResults(error, results) {
        if (error) {
            console.error(error)
        } else {
            **label = results[0].label** <-- This badboy
            mobilenet.predict(gotResults)
        }
    }
  

То, что я создаю https://codesandbox.io/s/dark-wave-dgrlg (это камера машинного обучения, которая определяет, что видит камера) Вы можете видеть, что метка в React не обновляется, а обновляется только метка в эскизе p5.

Мое исправление: я сделал что-то подобное setInterval(setLabel, 0) в своем коде, но, похоже, это не правильный шаблон? Есть ли лучший способ?

Решение: https://codesandbox.io/s/jovial-gates-usew3

Комментарии:

1. если вы поместите этот код в логику монтирования, подобную useEffect компоненту react, вы можете сохранить эту информацию в состоянии react. или «более хакерские» способы, такие как помещение значения в объект window или в localstorage

2. Здесь может помочь прокси . Он может использовать определенный обработчик для уведомления вашего компонента react о том, что произошло изменение значения метки. Можете ли вы также включить свой код react?

3. @DrewReese добавил сюда мой полный код: codesandbox.io/s/dark-wave-dgrlg

Ответ №1:

Как я могу сохранить это значение глобально?

Для глобальных состояний используйте хранилище redux. Вы можете отправить действие для сохранения этой метки.

ОБРАТИТЕ ВНИМАНИЕ, как указано в README,

myCustomRedrawAccordingToNewPropsHandler функция вызывается, если свойства компонента-оболочки меняются

Итак, я делюсь объектом sketch, чтобы быть явным. Эта функция перерисовки будет использоваться для доступа к родительской функции, которая фактически отправляет в хранилище redux.

 // sketch
export default function sketch(p) {
  // use custom redraw handler
  p.myCustomRedrawAccordingToNewPropsHandler = function (props) {
    // TODO: replace with actual label
    // get value out
    setInterval(() => props.gotResults(null, "done"), 5000);
  };
}
  
 // action
const key = "p5";
const SAVE_LABEL = `${key}/SAVE_LABEL`;

// action creator
function saveLabel(label) {
  return {
    type: SAVE_LABEL,
    payload: {
      label
    }
  }
}

export default function Sketch(props) {
  // dispatch inside component
  const dispatch = useDispatch()

  function gotResults(error, label) {
    if (error) {
      console.error(error);
      return;
    }

    dispatch(saveLabel(label));
  }

  return (
    <P5Wrapper
      sketch={sketch}
      gotResults={gotResults}
    />
  );
}

// TODO: add reducer
  

Пример песочницы: https://codesandbox.io/s/pedantic-breeze-54mde

Комментарии:

1. Как OP получает dispatch и action creator в объект sketch, чтобы sketch «отправить» его?

2. это часть списка задач, который ведет к обучению. 🙂

3. Правильно… но sketch функция является p5.js объект, а не Sketch компонент react, поэтому gotResults его нет в React. Решает ли этот ответ или объясняет решение проблемы OP с получением значения из эскиза p5? По крайней мере, попытайтесь связать код вашего решения с кодом OP.

4. setInterval было просто показать изменение состояния. В любом случае, вот грубый пример, показывающий нечто подобное. codesandbox.io/s/adoring-snow-l1qx3

5. Ах, круто! @JosephD. Спасибо! Я понял это. Я внес некоторые изменения в свой код. Теперь он работает (: codesandbox.io/s/jovial-gates-usew3 Это тебе за то, что ты мне так помог.

Ответ №2:

@josephD Я ломаю голову, пытаясь понять, как это работает в моем коде. Можете ли вы рассказать мне, как это работает? Спасибо!

Основываясь на этом файле, https://codesandbox.io/s/jovial-gates-usew3

Итак, в моем файле Sketch.tsx у меня есть такая строка команды props.setLabel(label) — это создание React prop на лету? Мы вызываем его setLabel и присваиваем ему значение label ?

   p5.myCustomRedrawAccordingToNewPropsHandler = function (props) {
    gotResults = (error, results) => {
        if (error) {
            console.error(error)
        } else {
            label = results[0].label
            **props.setLabel(label)** <-- this bad boy
            mobilenet.predict(gotResults)
        }
    }
}
  

Затем в нашем файле App.tsx кажется, что мы можем передать в setLabel него prop, который мы создали из Sketch.tsx? Я думал, что для использования React.useState мне нужно ввести что-то вроде setLabel(value) ? Нам не нужно вызывать setLabel(value) что-либо в файле App.tsx?

     const [label, setLabel] = React.useState("...")

return (
    <>
        <Frame>{label}</Frame>
        <P5Wrapper sketch={sketch} setLabel={setLabel} /> <-- How this magic happen?
    </>
)
  

Значение setLabel из useState теперь является реквизитом в P5Wrapper? И он принимает setLabel из Sketch.tsx в качестве атрибута?

Мое определение атрибута и prop: attribute={prop}

const [label, setLabel] = React.useState(«…»)

<P5Wrapper sketch={sketch} setLabel={setLabel} /> <— setLabel в качестве реквизита? Установить метку из Sketch.tsx в качестве атрибута?

Комментарии:

1. Эта концепция называется повышением состояния . Если состояние ( label ) находится в приложении (родительский компонент), то единственный способ обновить это состояние — через setLabel . setLabel in App передается как prop дочернему компоненту (P5Wrapper), чтобы дочерний компонент мог иметь средства для обновления родительского состояния.