简体   繁体   中英

how to pass the data from child component to parent component

now I am trying to send the data from child component to parent.

I have researched lot i didnt get any good solution. if there is a solution can any explain me to solve this.

APP.js

 import React from 'react';
    import IntegrationDownshift from './members'
    class App extends React.Component {
         constructor(props) {
          super(props);
          this.state = {
             Name: "Name from state...",
             Description: "Description from state...",
            Data:[data]
          }
       }
      render() {  
         return (
            <div>
     <IntegrationDownshift Members={this.state.Data}/>
           </div>
         );
      }
    }

export default App;`

members

var suggestions = []
var members=[];
function renderInput(inputProps) {
  const { InputProps, classes, ref, ...other } = inputProps;
  return (
    <TextField
      InputProps={{
        inputRef: ref,
        classes: {
          root: classes.inputRoot,
          input: classes.inputInput,
        },
        ...InputProps,
      }}
      {...other}
    />
  );
}
function renderSuggestion(suggestionProps) {
  const { suggestion, index, itemProps, highlightedIndex, selectedItem } = suggestionProps;
  const isHighlighted = highlightedIndex === index;
  const isSelected = (selectedItem || '').indexOf(suggestion.label) > -1;
  return (
    <MenuItem
      {...itemProps}
      key={suggestion.label}
      selected={isHighlighted}
      component="div"
      style={{
        fontWeight: isSelected ? 500 : 400,
      }}
    >
      {suggestion.label}
    </MenuItem>
  );
}
renderSuggestion.propTypes = {
  highlightedIndex: PropTypes.number,
  index: PropTypes.number,
  itemProps: PropTypes.object,
  selectedItem: PropTypes.string,
  suggestion: PropTypes.shape({ label: PropTypes.string }).isRequired,
};
function getSuggestions(value, { showEmpty = false } = {}) {
  const inputValue = deburr(value.trim()).toLowerCase();
  const inputLength = inputValue.length;
  let count = 0;
  return inputLength === 0 && !showEmpty
    ? []
    : suggestions.filter(suggestion => {
        const keep =
          count < 5 && suggestion.label.slice(0, inputLength).toLowerCase() === inputValue;
        if (keep) {
          count += 1;
        }
        return keep;
      });
}
function DownshiftMultiple(props) {
    suggestions=props.Members;
  const { classes } = props;
  const [inputValue, setInputValue] = React.useState('');
  const [selectedItem, setSelectedItem] = React.useState([]);
  function handleKeyDown(event) {
    if (selectedItem.length && !inputValue.length && event.key === 'Backspace') {
      setSelectedItem(selectedItem.slice(0, selectedItem.length - 1));
    }
  }
  function handleInputChange(event) {
    setInputValue(event.target.value);
  }
  function handleChange(item) {
    let newSelectedItem = [...selectedItem];
    if (newSelectedItem.indexOf(item) === -1) {
      newSelectedItem = [...newSelectedItem, item];
      members=newSelectedItem;   // **want to send this**
       props.onDataChanged(members)// **here i'm trying to send the value**
    }
    setInputValue('');
    setSelectedItem(newSelectedItem);
  }    
  const handleDelete = item => () => {
    const newSelectedItem = [...selectedItem];
    newSelectedItem.splice(newSelectedItem.indexOf(item), 1);
    setSelectedItem(newSelectedItem);
  };    
  return (
    <Downshift
      id="downshift-multiple"
      inputValue={inputValue}
      onChange={handleChange}
      selectedItem={selectedItem}
    >
      {({
        getInputProps,
        getItemProps,
        getLabelProps,
        isOpen,
        inputValue: inputValue2,
        selectedItem: selectedItem2,
        highlightedIndex,
      }) => {
        const { onBlur, onChange, onFocus, ...inputProps } = getInputProps({
          onKeyDown: handleKeyDown,
          placeholder: 'Select multiple Members',
        });

        return (
          <div className={classes.container}>
            {renderInput({
              fullWidth: true,
              classes,
              InputLabelProps: getLabelProps(),
              InputProps: {
                startAdornment: selectedItem.map(item => (
                  <Chip
                    key={item}
                    tabIndex={-1}
                    label={item}
                    className={classes.chip}
                    onDelete={handleDelete(item)}
                  />
                )),
                onBlur,
                onChange: event => {
                  handleInputChange(event);
                  onChange(event);
                },
                onFocus,
              },
              inputProps,
            })}

            {isOpen ? (
              <Paper className={classes.paper} square>
                {getSuggestions(inputValue2).map((suggestion, index) =>
                  renderSuggestion({
                    suggestion,
                    index,
                    itemProps: getItemProps({ item: suggestion.label }),
                    highlightedIndex,
                    selectedItem: selectedItem2,
                  }),
                )}
              </Paper>
            ) : null}
          </div>
        );
      }}
    </Downshift>
  );
}

DownshiftMultiple.propTypes = {
  classes: PropTypes.object.isRequired,
};

const useStyles = makeStyles(theme => ({
  root: {
    flexGrow: 1,
    height: 250,
  },
  container: {
    flexGrow: 1,
    position: 'relative',
  },
  paper: {
    position: 'absolute',
    zIndex: 1,
    marginTop: theme.spacing(1),
    left: 0,
    right: 0,
  },
  chip: {
    margin: theme.spacing(0.5, 0.25),
  },
  inputRoot: {
    flexWrap: 'wrap',
  },
  inputInput: {
    width: 'auto',
    flexGrow: 1,
  },
  divider: {
    height: theme.spacing(2),
  },
}));

let popperNode;

export default function IntegrationDownshift(props) {
    debugger
  const classes = useStyles();
  const Members=props.Members;
   props.onDataChanged("test")

  return (
    <div className={classes.root}>

      <DownshiftMultiple classes={classes} Members={Members}  />

    </div>
  );
}

I'm trying to implement this https://codesandbox.io/s/runh6 functionality which is material UI. I'm able to send the value from parent to child. but its not coming back to parent.

Now I want to read the members value in app.js. Is there a way to read the data in app.js

You can add a function to the parent component that will retrieve child components value.

Parent

  handleChildData = (value) => {
     do whatever you want to do with it
  }

 <IntegrationDownshift Members={this.state.Data} getData={this.handleChildData}/>

Child

<DownshiftMultiple classes={classes} Members={Members} childData={props.getData("test")}/>

A prop can be a function, eg onDataChanged :

class App extends React.Component {
  ...
  setData(data) {
    console.log('setting data in App', data)
  }
  render() {
    ...
    <IntegrationDownshift ... onDataChanged={this.setData} />
    ...


export default function IntegrationDownshift(props) {
  ...
  props.onDataChanged("test")
}

That would call the onDataChanged prop in each render, which makes little sense, more likely it should be called only inside an event handler in the child.

You can pass parent function to childred by using props .

That means that you can call parent function in child component.

App.js

import React from 'react';
import IntegrationDownshift from './members'
class App extends React.Component {
  constructor(props) {
     super(props);
     this.state = {
        Name: "Name from state...",
        Description: "Description from state...",
        Data:[] // init Data as empty
     }
  }
  addNewSelectedItem = (newItem) => {
    // you can add new Item from a child.
    this.setState(prevState => ({ Data: [...prevState.Data, newItem] }));
  }
  render() {  
     return (
        <div>
           <IntegrationDownshift addNewSelectedItem={this.addNewSelectedItem} Members={this.state.Data}/>
        </div>
     );
  }
}

export default App;

IntegrationDownshift Component

function DownshiftMultiple(props) {
...
handleChange(item) {
  //some operations
  props.addNewSelectedItem(item); // call parent function which is received by props.
}
...

You'll need to write a function in the parent that sets state, then pass that function to the child. Since it's bound to the parent you can run it in the child and the parent's state will be updated.

`import React from 'react';
    import IntegrationDownshift from './members'
    class App extends React.Component {
     constructor(props) {
      super(props);
      this.state = {
         Name: "Name from state...",
         Description: "Description from state...",
        Data:[data]
      }
    }
 *function getData(){
    this.setState({Name: 'this',
                   ....}) 
    }  *
   render() {  
     return (
        <div>
   <IntegrationDownshift Members={this.state.Data}/>
       </div>
     );
  }
 }

export default App;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM