Coder Social home page Coder Social logo

Comments (7)

based-ghost avatar based-ghost commented on May 29, 2024 1

@mrrotberry - O ya, it would appear that's a possible solution as well - glad it worked out for you! Also, I noticed that react-hook-form package just had a major release to v7.0.3 - not sure if that gives you even better options when working with thirdy-party libraries or not? I am still playing around with that package but it looks pretty promising.

from react-functional-select.

dannyvaughton avatar dannyvaughton commented on May 29, 2024

Ignore me, didn't see the methods.

from react-functional-select.

mrrotberry avatar mrrotberry commented on May 29, 2024

@dannyvaughton , hi) I seem to face the same problem, I can't figure out how to use this component with react-hook-form library. There is a specific case on the form, initially, when the page is loaded, I do not have an options array (it is loaded asynchronously), but after loading it, I need to set a certain value from it. I tried through the Controller component of the react-hook-form library, but how to pass and set the value property to the Select component, I cannot figure out.

P.S. @based-ghost , thank you a lot, for an easy and functional solution, maybe you can help with this case ?

from react-functional-select.

based-ghost avatar based-ghost commented on May 29, 2024

@mrrotberry - Ya for sure, I think I see what you are trying to accomplish (I believe most of the work will be offloaded to the wrapping parent component) - can you post a sample of the code, or snippets of what you have, so I can take a look?

But as a preliminary theory, I think you'd end up having to go down a path like this?

import { Select } from 'react-functional-select';
import { useState, useEffect, FunctionComponent } from 'react';
import { Card } from './helpers/styled';

const AsyncOptionsDemo: FunctionComponent = () => {
  const selectRef = useRef<SelectRef | null>(null);
  const [options, setOptions] = useState<any[]>([]);
  
  // Effect that loads initial options data from remote server
  useEffect(() => {
    const fetchData = async () => {
      try {
        const serverOptions = await mockHttpRequest();
        setOptions(serverOptions);
      } catch (e) {
        console.error(e);
      }
    };
	
    fetchData(); 
  }, []);

  // Effect that reacts to changes in 'options' state and will set initial value when options are populated from http request
  // Set value via 'ref' object using data of an item in the raw options
  useEffect(() => {
    if (options.length > 0) {
      const initValue= options[0];
      selectRef.current?.setValue(initValue);
    }
  }, [options]);

  return (
    <div id="app-root">
      <Select
       ref={selectRef}
       options={options}
      />
    </div>
  );
};

from react-functional-select.

mrrotberry avatar mrrotberry commented on May 29, 2024

oh, thanks for the detailed answer) yes indeed, over time, I already figured out how to work with ref, but I got the problem with react-hook-form.

import { FC } from "react";
import { Controller, useForm } from "react-hook-form";
import { Select } from "react-functional-select";

const CountryField: FC<{ countries?: { value: string; label: string }[] }> = ({
  countries,
}) => {
  const { control, setValue } = useForm<FormData>();

  return (
    <>
      <Controller
        name="country"
        control={control}
        rules={{
          required: true,
        }}
        // how to bind a value from a form with a value in a select?
        render={({ value, onChange }) => (
          <Select
            options={countries || []}
            onOptionChange={(option) => {
              onChange(option.value)
            }}
            isSearchable={false}
          />
        )}
      />

      {/* this code example serves to show an example of changing the value that 
      should be associated with the value of the select */}
      <button
        onClick={() => {
          if (Array.isArray(countries) && countries.length > 0) {
            setValue(
              "country",
              countries.find(({ id }) => id === "uk")
            );
          }
        }}
      >
        Set UK
      </button>
    </>
  );
};

@based-ghost the main question of my example above is how to associate the value of the field from the form with the value of the select, so that when the value of the form field changes, the value in the select?

from react-functional-select.

based-ghost avatar based-ghost commented on May 29, 2024

@mrrotberry - ah gotcha ok, I wasn't familiar with react-hook-form so I took a look a briefly. By ditching the Controller HOC and reversing the flow of handling the value updates we can get it to work. Below is a quick proof of concept I put together that highlights it:

import React, { useEffect, useCallback } from "react";
import { useForm } from "react-hook-form";
import { Select } from 'react-functional-select';

const createSelectOptions = (optionCount) => {
  const results = [];
  for (let i = 0; i < optionCount; i += 1) {
    results.push({
      value: i + 1,
      label: `Option ${i + 1}`
    });
  }
  return results;
};

const RF_SELECT_NAME = "rf-select";
const OPTIONS = createSelectOptions(100);

const App = () => {
  const { watch, register, setValue } = useForm();
  const watchRfSelectValue = watch(RF_SELECT_NAME);

  const getOptionValue = useCallback((option) => option.value, []);
  const getOptionLabel = useCallback((option) => option.label, []);

  const onOptionChange = useCallback((option) => {
    setValue(RF_SELECT_NAME, option);
  }, [setValue]);

  // Custom register Select component
  useEffect(() => {
    register(RF_SELECT_NAME);
  }, [register]);

  // Verify value from select control is being passed to control
  useEffect(() => {
    console.log(watchRfSelectValue);
  }, [watchRfSelectValue]);

  return (
    <div>
      <Select
        options={OPTIONS}
        getOptionValue={getOptionValue}
        getOptionLabel={getOptionLabel}
        onOptionChange={onOptionChange}
      />
    </div>
  );
};

export default App;

The issue is that it looks like react-hook-form is designed to work with uncontrolled components (which aligns more with the newer design patterns when working with hooks and function components) and the Controller HOC was added as a backwards compatibility type thing for components that were built based on the legacy class API. Let me know if this solves your issue.

from react-functional-select.

mrrotberry avatar mrrotberry commented on May 29, 2024

@based-ghost hmm, it looks like I managed to achieve the goal with the help of your examples) I combined your original example with ref and custom registration, here is a link to a working example - CodeSandbox

P.S. Thank you again for your attention to my problem, your select solution turned out to be really very cool!

from react-functional-select.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.