What is the best way to integrate react-final-form with material-ui-chip-input in a seamless manner

Currently, I am utilizing Material UI Chip Input wrapped with Field from react-final-form. https://i.sstatic.net/vJKM1.jpg

The main objective is to restrict the number of "CHIPS" to a maximum of 5.

Chips serve as concise elements representing inputs, attributes, or actions.

For more details, you can refer to the Material UI documentation.

In this setup, there are two distinct states being employed:

  1. React useState
  2. Internal states within react-final-form

This approach seems redundant because internal state management is already handled by react-final-form. However, despite my efforts, it hasn't been functioning correctly. This is merely a demonstration of what has been implemented so far.

The issues encountered with this implementation are:

  1. The chip count limitation does not take effect.
  2. Field values within react-final-form fail to update upon deleting a chip.
import ChipInput from 'material-ui-chip-input'
import { Field } from 'react-final-form'

const [state, setState] = useState([])

const AddChip = useCallback(
    (chip) => {
        if (state.length + 1 <= 5) {
        setState((prev) => ([...prev.tags, chip]))
        }
    },
    [setState, state.length]
)

const DeleteChip = useCallback(
    (chip) => {
        setState((prev) => (...prev.state.filter((p) => p !== chip)]
        }))
    },
    [setState]
)

  return (
    <Field name="states" validate={isRequired} >
          {({ input: { value, onChange, ...rest }, meta }) => {
     <ChipInput
        defaultValue={Array.isArray(value) ? value : []}
        onChange={(event) => {
            AddChip(event)
            onChange(event)
        }}
        onDelete={DeleteChip} 
       />
      }}
    </Field>
  )

Find additional resources here: - Material UI Chip Input package - React Final Form documentation - View the CodeSandbox demo

Answer №1

Here are some key points to consider:

  • Avoid duplicating state management by allowing react final form to handle the state for you.
  • When initializing the FORM, pass an empty array as the initial state instead of using defaultValues for the Field component.
  • If utilizing the material-ui-chip-input package in controlled mode, make sure to use the onAdd function according to the documentation.
  • Include the value prop when using Chipinput.
  • For better organization, consider using a functional child component instead of a render-prop inside the <Form />.

Check out the code snippet below:

// Import necessary components
import ChipInput from "material-ui-chip-input";
import { Form, Field } from "react-final-form";

// Define the main App component
export default function App() {
  return (
    <Form
      initialValues={{
        states: []
      }}
      onSubmit={() => console.log("submitted")}
    >
      {({ values, onSubmit }) => (
        <form onSubmit={onSubmit}>
          <Field name="states">
            {({ input: { value, onChange } }) => (
              <ChipInput
                value={value}
                alwaysShowPlaceholder={true}
                placeholder="type states here"
                onAdd={(newVal) => {
                  if (value.length >= 5) return;
                  const newArr = [...value, newVal];
                  onChange(newArr);
                }}
                onDelete={(deletedVal) => {
                  const newArr = value.filter((state) => state !== deletedVal);
                  onChange(newArr);
                }}
              />
            )}
          </Field>
          <p>Managing state with react useStates</p>

          <p>Current form values via react-final-form:</p>
          <pre
            style={{
              backgroundColor: "rgba(0,0,0,0.1)",
              padding: "20px"
            }}
          >
            {JSON.stringify(values, 0, 2)}
          </pre>
        </form>
      )}
    </Form>
  );
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

AngularJS Time Range Selector: A Slider Solution

I have successfully implemented a time range slider using Jquery and JqueryUI. $("#slider-range").slider({ range: true, min: 0, max: 1440, step: 15, values: [600, 720], slide: function (e, ui) { var hours1 = Math.floor(ui.values[0] / 60); var minu ...

View content from a text file on a webpage

Hi everyone, I could really use some assistance with a project I'm currently working on. As someone who is new to programming, I am facing a challenge. My goal is to showcase the contents of a plain text file on a webpage. This text file, titled titl ...

What is the process for importing the util module in Node.js?

I attempted to use the isDeepStrictEqual() method for object comparison but encountered this error: util.isDeepStrictEqual() is not a function After checking the official documentation, I found out that this method was introduced in Node.js v9.0.0 w ...

Using Angular.js, apply the "visible" class conditionally based on a variable

My Cordova application is built with angular.js and consists of the following 2 files: app.html <div ng-controller="MyAppCtrl as myApp" ng-class="myApp.isWindows() ? 'windows' : ''"> and app.controller MyAppCtrl.$inject = [&ap ...

"Enhance your website with Express.js and eliminate the need for full

As I continue to work on my website, I am faced with a challenge. While the page is not overly large, I want to ensure that when navigating to different tabs in the navbar, the entire site does not have to reload each time. Currently, I am using express.js ...

I am receiving a 401 error when attempting to verify the token following a successful login

I've been working on a small project utilizing VueJS, Vue Router, and Laravel for the backend. Despite several attempts, I haven't been successful in implementing navigation guards. My login component is functioning properly. Here's my log ...

AngularJS - managing checkboxes and dropdownlists

When I talk about the topic of depending on checkboxes from a dropdown list, I mention that I populate my dropdown list with data from the controller: @RequestMapping(value = "/all", method = GET) public List<Warehouse> findAll(){ return warehous ...

The Google Pie chart is displaying outside of the designated div area when placed inside a dropdown menu

Encountering an issue with my pie chart rendering outside of its parent div when placed within a dropdown menu. The chart successfully loads after the page is loaded, but only displays correctly if I hover over the dropdown and allow it to load. If I do ...

The chosen option does not equal the value retrieved by using jQuery's

I am perplexed by the situation at hand. It seems that there is a discrepancy in the selected option of my select element. Despite appearing as the empty default option on top, the inspected element reveals it displaying a value of 13. https://i.sstatic.n ...

The 'disable' prop in Material UI textfield fails to update after the initial change

Currently, I am working on a program that involves radio switches, each representing a different boolean value. This program aims to toggle the 'disable' property of a textfield based on the boolean value selected by the user. The issue I am faci ...

Turning off the transpiler in Vue Webpack to simplify the debugging process

Debugging in Vue can be quite challenging, especially when it comes to setting breakpoints and stepping through the code. The issue seems to stem from the transpiling of javascript ES6/ES2015/ES2016/ES2017 to ES5. While source maps provide some assistance, ...

Customize the color of the React Material UI progress bar across all variants

Is there a way to customize the colors of the Material UI linear progress bar for all variants? Below are two solutions I tried. import React from "react"; import { makeStyles } from "@material-ui/core/styles"; import LinearProgress fro ...

In JavaScript, a prompt is used to request the user to input a CSS property. If the input is incorrect,

Implement a while loop that continuously prompts the user to enter a color. If the color entered matches a CSS property such as blue, red, or #000000: The background will change accordingly, but if the user enters an incorrect color, a message will be dis ...

Struggling to find a solution for changing the color of a select box when an option is chosen

Here's an example of the HTML I'm working with: <select onclick="colorchanger()"> <option name="white" value="0">--Select--</option> <option name="red" value="1">Work</option> <option name="green" value="2" ...

A guide on retrieving bytecode from a specific PDF using Angular

Can anyone help me with extracting the bytecode from a selected PDF file to save it in my database? I keep encountering an error stating that my byte is undefined. Could someone please review my code and identify what might be causing this issue? I attemp ...

Is the variable not being initialized outside of the function?

I'm really struggling with this async issue. I can't seem to get it to work because the summonerData array is not being set. I have a feeling it has something to do with async, but I'm not sure how to troubleshoot it. var summonerName = req ...

When JQuery is written in a separate file, it does not get applied in the HTML file

I've encountered an issue that seems to have similarities to others, but despite trying various solutions and writing JQuery code in a JS file, I can't seem to get it to work properly. When I include the path for the JS and JQuery version in the ...

Configuring Proxy Settings for WebpackDevServer

I need assistance setting up a proxy using WebpackDevServer in my React/Node chrome extension. Currently, my server is running on localhost:4000, and the React frontend is on localhost:5000. When trying to access the route /api/user/ticket using Axios, I ...

"Combining background images with javascript can result in displaying visual elements

Hello! I am in need of assistance with a CSS + Javascript fog effect that I have developed. It is functioning properly on Firefox, Opera, and Chrome but encountering issues on IE and Edge browsers. The effect involves moving two background images within a ...

The chosen option in the q-select is extending beyond the boundaries of the input field

Here's the code snippet I used for the q-select element: <q-select square outlined fill-input standout="bg-grey-3 text-white" v-model="unit_selection" :options="units&qu ...