I have a search bar (the parent) that has 3 child components - location dropdown, calender(date picker) and duration dropdown. By default the location is selected to wherever the user's location is. I want a change of focus to date picker where the calendar dropdown is opened automatically after there's an interaction with the first dropdown (location dropdown) and same applies from the second input to the third input. How can I go about doing this?
Parent:
import React, { Component } from 'react';
import { Icon, Btn } from '#appearhere/bloom';
import Title from '../Title';
import LocationDropdown from '../LocationDropdown';
import AppearDateCalendar from '../AppearDateCalendar';
import DurationDropdown from '../DurationDropdown';
import css from './SegmentationBar.css';
import i18n from 'utils/i18n/i18n';
const t = i18n.withPrefix('client.apps.static.screens.home.header.segmentation');
type Props = {
onLocationDropdownChange: Function,
onDateChange: Function,
onDurationChange: Function,
onSubmit: Function,
onMobileSearchClick: Function,
fullSupport: boolean,
};
export default class SegmentationBar extends Component<Props> {
render() {
const {
onLocationDropdownChange,
onDateChange,
onDurationChange,
onSubmit,
fullSupport,
} = this.props;
return (
<div className={css.container}>
<Title />
{fullSupport && (
<div className={css.barWrapper}>
<div className={css.segmentationBar}>
<LocationDropdown onDropdownChange={onLocationDropdownChange} />
<AppearDateCalendar onDateChange={onDateChange} />
<DurationDropdown onDropdownChange={onDurationChange} />
</div>
<div className={css.submitButton} onClick={onSubmit}>
<Icon name="search" />
</div>
</div>
)}
</div>
);
}
}
Children:
1st dropdown:
import React, { Component } from 'react';
import i18n, { getCurrentLocale } from 'utils/i18n/i18n';
import { Icon } from '#appearhere/bloom';
import locationOrder from './locationOrder.json';
import locations from './locations.json';
import css from './LocationDropdown.css';
const t = i18n.withPrefix('client.apps.static.screens.home.header.segmentation.location');
type Props = {
onDropdownChange: Function,
};
type Location = {
key: string,
name: string,
country: string,
placeId: string,
searchString: string,
priority: number,
};
class LocationDropdown extends Component<Props> {
componentDidMount() {
const selectedCity = this.findCitiesForCountry(locationOrder[getCurrentLocale()][0])[0];
this.props.onDropdownChange(selectedCity.searchString, selectedCity.placeId);
}
citySorting = (a: Location, b: Location): number => {
if (a.priority > b.priority) return 1;
if (a.priority < b.priority) return -1;
if (a.name >= b.name) return 1;
return -1;
};
findCitiesForCountry = (countryKey: string): Array<Location> =>
locations
.filter((location: Location): boolean => location.country === countryKey)
.sort(this.citySorting);
handleDropdownChange = (event: SyntheticInputEvent<EventTarget>) => {
const city = locations.find(
(location: Location): boolean => location.key === event.target.value,
);
this.props.onDropdownChange(city.searchString, city.placeId);
};
renderSelectOptions = (countryKey: string): React.Node => {
const cities = this.findCitiesForCountry(countryKey);
return cities.map((city: Location): React.Node => (
<option key={city.key} value={city.key}>
{city.name}
</option>
));
};
renderSelectOptionGroups = (): React.Node =>
locationOrder[getCurrentLocale()].map((countryKey: string): React.Node => (
<optgroup key={countryKey} label={t(countryKey)}>
{this.renderSelectOptions(countryKey)}
</optgroup>
));
render() {
return (
<div className={css.LocationDropdown}>
<div className={css.searchIcon}>
<Icon name="search" />
</div>
<select role="listbox" className={css.locationSelect} onChange={this.handleDropdownChange}>
{this.renderSelectOptionGroups()}
</select>
</div>
);
}
}
2nd input:
Calendar:
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import i18n from 'utils/i18n/i18n';
import { DayPicker } from '#appearhere/bloom';
import moment from 'utils/moment/moment';
import cx from 'classnames';
import css from './AppearDateCalendar.css';
const t = i18n.withPrefix('client.apps.static.screens.home.header.segmentation.calendar');
type Props = {
onDateChange: Function,
};
type State = {
calendarOpen: boolean,
month: moment,
day: ?moment,
};
export default class AppearDateCalendar extends Component<Props, State> {
state = {
calendarOpen: false,
month: moment(),
day: undefined,
};
componentDidMount() {
document.addEventListener('mousedown', this.handleClickOutside);
}
componentWillUnmount() {
document.removeEventListener('mousedown', this.handleClickOutside);
}
handleClickOutside = (event: SyntheticMouseEvent<EventTarget>) => {
const currentNode = ReactDOM.findDOMNode(this);
if (currentNode && !currentNode.contains(event.target)) {
this.setState({ calendarOpen: false });
}
};
handleCalendarClick = () => {
this.setState({ calendarOpen: !this.state.calendarOpen });
};
handleMonthChange = (_event: any, newMonth: moment) => {
this.setState({ month: newMonth });
};
handleDaySelect = (_event, day: moment) => {
this.props.onDateChange(day);
this.setState({ day, calendarOpen: false });
};
dateDisplayText = (): string => {
if (this.state.day) return this.state.day.format('Do MMM, YY');
return t('choose_date');
};
render() {
return (
<div className={cx(css.appearDateCalendar, this.state.calendarOpen ? css.focused : '')}>
<div onClick={this.handleCalendarClick}>
<h5 className={css.heading}>{t('heading')}</h5>
<p className={css.dateText}>{this.dateDisplayText()}</p>
</div>
{this.state.calendarOpen && (
<div className={css.calendarDropdown}>
<DayPicker
month={this.state.month}
onInteraction={this.handleDaySelect}
onMonthChange={this.handleMonthChange}
/>
</div>
)}
</div>
);
}
}
3rd dropdown:
Duration:
import React, { Component } from 'react';
import i18n from 'utils/i18n/i18n';
import css from './DurationDropdown.css';
import durations from './durations.json';
const t = i18n.withPrefix('client.apps.static.screens.home.header.segmentation.duration');
type Props = {
onDropdownChange: Function,
};
type Duration = {
name: string,
maxDuration: number,
highValue: boolean,
};
export default class DurationDropdown extends Component<Props> {
handleDropdownChange = (event: SyntheticInputEvent<EventTarget>) => {
const durationIndex = event.target.value;
const duration = durations[durationIndex];
this.props.onDropdownChange(duration.maxDuration, duration);
};
renderDurationOptions = (): React.Node =>
durations.map((duration: Duration, index: number): React.Node => (
<option key={duration.name} value={index}>
{t(duration.name)}
</option>
));
render() {
return (
<div className={css.durationDropdown}>
<h5 className={css.heading}>{t('heading')}</h5>
<select role="listbox" className={css.durationSelect} onChange={this.handleDropdownChange}>
<optgroup label={t('booking_duration')}>{this.renderDurationOptions()}</optgroup>
</select>
</div>
);
}
}
You should read about React refs: https://reactjs.org/docs/refs-and-the-dom.html
You can create a ref per input, and pass it from your parent to the 3 children, and use ref.current.focus() in your dropdown handlers.
Related
Can anyone help me explain it, because when use functional it work, but not when use class component
Different class component and func component in handle event react.
fyi it take input text search on child and at parent doing handle event and other
child use functional
import React from "react";
const Header = ({searchTitle,onSearch}) => {
return (
<div>
<header>
<h1>Notes</h1>
<div className="search">
<input
type="text"
placeholder="Search..."
value={searchTitle}
onChange={onSearch}
></input>
</div>
</header>
</div>
);
};
export default Header;
child use class component
import React, { Component } from "react";
export class HeaderPage extends Component {
render() {
const searchTitle = this.props.searchTitle;
const onSearch = this.props.onSearchHandler;
return (
<header>
<h1>Notes</h1>
<div className="search">
<input
type="text"
placeholder="Search..."
value={searchTitle}
onChange={onSearch}
></input>
</div>
</header>
);
}
}
export default HeaderPage;
parent class componet
import React, { Component } from "react";
import HeaderPage from "../organisms/HeaderPage";
import MainPage from "../organisms/MainPage";
import FooterPage from "../organisms/FooterPage";
import { getInitialData } from "../../utils/data";
import Header from "../organisms/Header";
export class PageNote extends Component {
constructor(props) {
super(props);
this.state = {
dataNotes: getInitialData(),
dataNotesFiltered: [],
searchTitle: "",
};
//binding
this.onAddNoteHandler = this.onAddNoteHandler.bind(this);
this.onDeleteHandler = this.onDeleteHandler.bind(this);
this.onArchivedHandler = this.onArchivedHandler.bind(this);
this.onSearchHandler = this.onSearchHandler.bind(this);
}
onAddNoteHandler({ title, body }) {
this.setState((prevState) => {
return {
dataNotes: [
...prevState.dataNotes,
{
id: +new Date(),
title,
body,
archived: false,
createdAt: new Date().toLocaleDateString(),
},
],
};
});
}
onDeleteHandler(id) {
const dataNotes = this.state.dataNotes.filter(
(dataNote) => dataNote.id !== id
);
this.setState({ dataNotes });
}
onArchivedHandler(id) {
const dataNotes = this.state.dataNotes.map((note) => {
if (note.id === id) {
return { ...note, archived: !note.archived };
} else {
return note;
}
});
this.setState({ dataNotes });
}
onSearchHandler(event) {
this.setState(() => {
return {
searchTitle: event.target.value,
};
});
}
render() {
console.log(this.state.dataNotes);
console.log(`search ${this.state.searchTitle}`);
const dataNotes = this.state.dataNotes.filter((note) =>
note.title.toLowerCase().includes(this.state.searchTitle.toLowerCase())
);
return (
<>
<HeaderPage
searchTitle={this.state.searchTitle}
onSearch={this.onSearchHandler}
></HeaderPage>
<Header
searchTitle={this.state.searchTitle}
onSearch={this.onSearchHandler}
></Header>
<MainPage
dataNotes={dataNotes}
addNote={this.onAddNoteHandler}
onDelete={this.onDeleteHandler}
onArchive={this.onArchivedHandler}
></MainPage>
<FooterPage></FooterPage>
</>
);
}
}
export default PageNote;
I am making project, where you get books cards using Google Books API. I need to count amount of books I get in the end and print in in Header.js(after search). I think I need to add new parameter like 'count' in constructor that will get books.length but still don't know how to pass it in the end.
Books.js
import React, { Component } from 'react';
import SearchArea from './SearchArea';
import request from 'superagent';
import BookList from './BookList';
class Books extends Component {
constructor(props){
super(props);
this.state = {
books: [],
searchField: '',
sort: ''
}
}
searchBook = (e) => {
e.preventDefault();
request
.get("https://www.googleapis.com/books/v1/volumes")
.query({ q: this.state.searchField })
.then((data) => {
console.log(data);
const cleanData = this.cleanData(data)
this.setState({ books: cleanData })
})
}
handleSearch = (e) => {
this.setState ({ searchField: e.target.value })
}
handleSort = (e) => {
console.log(e.target.value)
this.setState({sort: e.target.value})
}
cleanData = (data) => {
const cleanedData = data.body.items.map((book) => {
if(book.volumeInfo.hasOwnProperty('publishedDate') === false){
book.volumeInfo['publishedDate'] = '0000';
}
else if(book.volumeInfo.hasOwnProperty('imageLinks') === false) {
book.volumeInfo['imageLinks'] = {thumbnail: 'https://vignette.wikia.nocookie.net/pandorahearts/images/a/ad/Not_available.jpg/revision/latest?cb=20141028171337'}
}
console.log(this.state.books.length)
return book;
})
return cleanedData;
}
render(){
const sortedBooks = this.state.books.sort((a,b) => {
if(this.state.sort === 'Newest') {
return parseInt(b.volumeInfo.publishedDate.substring(0,4)) - parseInt(a.volumeInfo.publishedDate)
}
else if(this.state.sort === 'Oldest') {
return parseInt(a.volumeInfo.publishedDate.substring(0,4)) - parseInt(b.volumeInfo.publishedDate)
}
})
return (
<div>
<SearchArea searchBook = {this.searchBook} handleSearch={this.handleSearch} handleSort={this.handleSort}/>
<BookList books={this.state.books} />
</div>
);
}
}
export default Books;
SearchArea.js
import React from 'react'
const SearchArea = (props) => {
return(
<div className="search-area">
<form onSubmit={props.searchBook} action="">
<input onChange={props.handleSearch} type="text"/>
<button id="search" type="submit">Search</button>
<select defaultValue="Sort" onChange={props.handleSort}>
bled v<option disaalue="Sort">Sort</option>
<option value="Newest">Newest</option>
<option value="Oldest">Oldest</option>
</select>
</form>
</div>
)
}
export default SearchArea;
BookList.js
import React from 'react';
import BookCard from './BookCard';
const BookList = (props) => {
return(
<div className="list">
{
props.books.map((book,i) => {
return <BookCard
key={i}
image={book.volumeInfo.imageLinks.thumbnail}
title={book.volumeInfo.title}
author={book.volumeInfo.authors}
published={book.volumeInfo.publishedDate}
/>
})
}
</div>
)
}
export default BookList;
Header.js
import React from 'react';
const Header = () => {
return(
<header>
<h1>Book Cards</h1>
</header>
)
}
export default Header;
I have been building a trivia game using the Open Trivia API and I am getting an error that I have been trying to figure out but am stuck on. It says: Invalid value for prop value on tag. Either remove it from the element, or pass a string or number value to keep it in the DOM.
I will include my code pages. Thank you in advance for you help.
App.js page:
import React from 'react'
import './App.css'
import axios from 'axios'
import Questions from './components/questions'
import CategorySelector from './components/CategorySelector'
class App extends React.Component {
constructor () {
super()
this.state = {
categories: [],
selectedCategory: null
}
this.selectedCategory = this.selectedCategory.bind(this)
}
componentDidMount () {
axios
.get('https://opentdb.com/api_category.php')
.then(response => {
console.log(response.data)
this.setState({
categories: response.data.trivia_categories
})
})
}
selectedCategory (category) {
this.setState({ selectedCategory: category })
}
render () {
const { categories, selectedCategory } = this.state
return (
<div className='App'>
<h2>Trivia Game</h2>
{
selectedCategory
? <Questions selectedCategory={selectedCategory} />
: (
<CategorySelector
categories={categories}
onSelect={event => selectedCategory}
selectedCategory={this.selectedCategory}
/>
)
}
</div>
)
}
}
export default App
CategorySelector.js page:
import React from 'react'
class CategorySelector extends React.Component {
render () {
const { categories, selectedCategory, onSelect } = this.props
return (
<div className='CategorySelector'>
<select
value={selectedCategory} onChange={onSelect}
>
<option value=''>-- No category selected --</option>
{categories.map(category => (
<option value={selectedCategory} key={category.id}>{category.name}</option>
))}
</select>
</div>
)
}
}
export default CategorySelector
Question.js page
import React from 'react'
import axios from 'axios'
class Questions extends React.Component {
constructor () {
super()
this.state = {
questions: [],
currentQuestionIndex: 0
}
this.handleNextQuestion = this.handleNextQuestion.bind(this)
}
componentDidMount () {
const qUrl = `https://opentdb.com/api.php?amount=3&category=${this.props.selectedCategory.id}`
axios
.get(qUrl)
.then(response => {
console.log(response.data)
this.setState({
questions: response.data.results
})
})
}
handleNextQuestion () {
this.setState({ currentQuestionIndex: this.state.currentQuestionIndex + 1 })
}
render () {
const { selectedCategory } = this.props
const { questions, currentQuestionIndex } = this.state
const currentQuestion = questions[currentQuestionIndex]
let answers = []
if (currentQuestion) {
answers = currentQuestion.incorrect_answers.concat([currentQuestion.correct_answer])
}
return (
<div className='Questions'>
<h2>{selectedCategory.name} Questions</h2>
{currentQuestion && (
<div>
<h3>{currentQuestion.questions}</h3>
<div>
{answers.map((answer, index) => <p key={index}>{answer}</p>)}
</div>
</div>
)}
{(currentQuestionIndex < questions.length - 1) &&
<button onClick={this.handleNextQuestion}>Next Question</button>}
</div>
)
}
}
export default Questions
While passing the prop, you're referring the state variable as this.selectedCategory
Change this line
selectedCategory={this.selectedCategory}
to
selectedCategory={selectedCategory}
I am newbie to react, redux-saga, I have a dropdown in page Display, when I select it move to respective component (eg. policy, score), In Component Pages, I have a button Add New, on clicking it will navigate to a page as mentioned in link url , which is a page having cancel button, on cancelling it returns to the Display.js but no dropdown selected,
I would like to keep the state articleMode, when navigating to a page and returning back to same page,
articleMode returns to state -1 instead of selected component Policy or Score
actions.js
export const updateArticleMode = data => {
console.log(data.body);
return {
type: CONSTANTS.UPDATE_ARTICLE_MODE,
data: data.body
};
};
queryReducer.js
import * as CONSTANTS from "../constants/constants";
const initialState = {
articleMode: ""
}
case CONSTANTS.UPDATE_ARTICLE_MODE: {
return {
...state,
articleMode: data.mode
};
}
export default queryReducer;
constants.js
export const UPDATE_ARTICLE_MODE = "UPDATE_ARTICLE_MODE";
Display.js
import React from "react";
import { connect } from "react-redux";
import Policy from "../policy";
import Score from "./../score";
import { updateArticleMode } from "../../../../actions/actions";
const articleMode = [
{ name: "Select", id: "-1" },
{ name: "Score", id: "Score" },
{ name: "Policy", id: "Policy" }
]
class Display extends React.PureComponent {
constructor(props) {
super(props);
this.state = {
articleMode: "-1"
};
}
componentWillMount = () => {
this.setState({ articleMode: this.props.queryData.articleMode || "-1" });
};
_getComponent = () => {
const { articleMode } = this.state;
if (articleMode === "Policy") {
return <DisplayPolicy></DisplayPolicy>;
}
if (articleMode === "Score") {
return <DisplayScore></DisplayScore>;
}
}
render() {
return (
<React.Fragment>
<select name="example"
className="simpleSearchSelect1"
value={this.state.articleMode}
onChange={event => {
this.setState({ articleMode: event.target.value });
this.props.dispatch(
updateArticleMode({ body: { mode: event.target.value } })
);
}}
style={{ marginLeft: "2px" }}
>
{articleMode.length != 0 &&
articleMode.map((option, index) => {
const { name, id } = option;
return (
<option key={index} value={id}>
{name}
</option>
);
})}
</select>
{this.state.articleMode === "-1"
? this._renderNoData()
: this._getComponent()}
</React.Fragment>
)}
const mapStateToProps = state => {
return {
queryData: state.queryData
};
};
export default connect(mapStateToProps)(Display);
}
DisplayPolicy.js
import React from "react";
class DisplayPrivacyPolicy extends React.Component {
constructor(props) {
super(props);
}<Link
to={{
pathname: "/ui/privacy-policy/addNew",
state: {
language: "en"
}
}}
>
<button className="page-header-btn icon_btn display-inline">
<img
title="edit"
className="tableImage"
src={`${process.env.PUBLIC_URL}/assets/icons/ic_addstore.svg`}
/>
{`Add New`}
</button>
</Link>
AddNew.js
<Link
to =pathname: "/ui/display",
className="btn btn-themes btn-rounded btn-sec link-sec-btn"
>
Cancel
</Link>
I'm trying to add and remove a dropdown field on click of two buttons:
one 'Add' button which adds/creates a new dropdown field (predefined with options & values)
A 'Remove' button next to each dropdown (in order to remove them individually)
This is a multi page app so I'm using React Router to navigate from one page to another - so to keep the state I'm using Redux.
I managed to add and remove the dropdown fields on click of the buttons - but I'm facing two issues:
I'm falling to save the dropdowns to the store, so if I navigate to another page and come back, the added dropdowns are gone from the page
Anytime a new dropdown is added, the option of the selects is reset
Here is my code so far:
import React from 'react'
import { connect } from 'react-redux'
import { addData, saveSelect, removeSelect } from '../actions.js'
class AddSelectField extends React.Component {
constructor(props){
super(props);
this.state = {
inputSelect: []
}
}
saveData = (e) => {
let data = {}
data[e.target.name] = e.target.value
this.context.store.dispatch(
addData(data)
)
}
addInput = () => {
const inputSelect = this.state.inputSelect.concat(this.renderDropDown);
this.setState({ inputSelect });
this.context.store.dispatch(
saveSelect(this.state.inputSelect)
)
}
removeInput = (item) => {
let index = this.state.inputSelect.indexOf(item);
let newInputSelect = this.state.inputSelect;
newInputSelect.splice(index,1);
this.setState({
inputSelect: newInputSelect
});
this.context.store.dispatch(
removeSelect(newInputSelect)
)
}
renderDropDown = (el, index) => {
return(
<div>
<select
key={index}
name={'document-'+ index}
value={'document-'+ index}
onChange = {this.saveData}
>
<option value="0">Please Select</option>
<option value="1">Australia</option>
<option value="2">France</option>
<option value="3">United Kingdom</option>
<option value="4">United States</option>
</select>
<button onClick={ this.removeInput }>Remove</button>
</div>
)
}
render(){
return(
<div>
<button onClick={ this.addInput }>Add</button>
<div className="inputs">
{this.state.inputSelect.map(this.renderSelect)}
</div>
</div>
)
}
}
class AccountUpgrade extends React.Component {
constructor(props) {
super(props);
}
continueClick() {
this.context.router.push('/AccountUpgrade/Confirmation/')
}
render(){
return (
<div>
<div className="row">
<AddSelectField />
<ButtonRow
primaryProps={{
children: 'Continue',
onClick: this.continueClick.bind(this)
}} />
</div>
</div>
)
}
}
AccountUpgrade.contextTypes = {
store: React.PropTypes.object.isRequired,
router: React.PropTypes.object.isRequired
}
const mapStateToProps = (state) => {
return {
store: state.EligibleAbout
}
}
const EligibleAbout = connect(mapStateToProps)(AccountUpgrade)
export default EligibleAbout
action.js
export const ADD_DATA = 'ADD_DATA'
export const ADD_SELECT = 'ADD_SELECT'
export const REMOVE_SELECT = 'REMOVE_SELECT'
export function addData(data) {
return { type: ADD_DATA, data }
}
export function saveSelect(data) {
return { type: ADD_SELECT, data }
}
export function removeSelect(data) {
return { type: REMOVE_SELECT, data }
}
reducer.js
import ObjectAssign from 'object.assign'
import { combineReducers } from 'redux'
import { ADD_DATA, ADD_SELECT, REMOVE_SELECT } from './actions'
function EligibleAbout(state = {}, action){
switch (action.type){
case ADD_DATA:
return ObjectAssign({}, state, action.data)
case ADD_SELECT:
return ObjectAssign({}, state, action.data)
case REMOVE_SELECT:
return ObjectAssign({}, state, action.data)
default:
return state
}
}
const FormApp = combineReducers({
EligibleAbout
})
export default FormApp
You are managing state in the component as well as in the reducer. In the render function, you are always taking values of inputSelect from the state which is blank initially. You are not using values stored in the reducer for rendering purpose that's why you are not getting it on coming back.
Do not store inputSelect in your component state. Just store that in reducer and use inputSelect from reducer for rendering purpose.
import React, { PropTypes } from 'react'
import { connect } from 'react-redux'
import uuidV4 from 'uuid/v4'
class AddSelectField extends React.Component {
static propTypes = {
ids: PropTypes.array,
removeSelect: PropTypes.func,
saveSelect: PropTypes.func,
}
static defaultProps = {
ids: [],
}
saveData = (e) => {
// Just do your stuff here.
}
addInput = () => {
this.props.saveSelect(uuidV4())
}
removeInput = index => {
this.props.removeSelect(index)
}
renderDropDown = (id, index) => {
return (
<div>
<select
key={id}
name={id}
onChange={this.saveData}
>
<option value="0">Please Select</option>
<option value="1">Australia</option>
<option value="2">France</option>
<option value="3">United Kingdom</option>
<option value="4">United States</option>
</select>
<button
onClick={() => {
this.removeInput(index)
}}>
Remove
</button>
</div>
)
}
render() {
const ids = this.props.ids
return(
<div>
<button onClick={ this.addInput }>Add</button>
<div className="inputs">
{ids.map(this.renderDropDown)}
</div>
</div>
)
}
}
const mapStateToProps = state => {
const eligibleAbout = state.EligibleAbout
return {
ids: eligibleAbout.ids,
}
}
const EligibleAbout = connect(mapStateToProps, { saveSelect, removeSelect })(AddSelectField)
export default class AccountUpgrade extends React.Component {
continueClick() {
// do your stuff here.
}
render() {
return (
<div>
<div className="row">
<EligibleAbout />
</div>
</div>
)
}
}
Updated Reducer is:
function eligibleAbout(state = { ids: [] }, action = {}){
switch (action.type) {
case ADD_DATA:
// set according to requirement.
case ADD_SELECT:
return {
...state,
ids: [].concat(state.ids, action.data),
}
case REMOVE_SELECT:
return {
...state,
ids: state.ids.filter((id, index) => (index !== action.data)),
}
default:
return state
}
}
If I had been at your place, I would do it like this except state management. I would recommend using immutable will be a good option for state management.
Note: I have only implemented adding and removing input functionality. Not clear about your saveData function requirement.