如何将数据从 child 组件传递到 parent 组件

how to pass the data from child component to parent component

现在我正在尝试将数据从 child 组件发送到 parent。

我研究了很多我没有找到任何好的解决方案。如果有解决方案可以解释我解决这个问题。

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;`

成员

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>
  );
}

我正在尝试实现此 https://codesandbox.io/s/runh6 功能,即 material UI。我能够将值从 parent 发送到 child。但它不会回到 parent.

现在我想读取 app.js 中的 members 值。有没有办法读取 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]
      }
    }
 *function getData(){
    this.setState({Name: 'this',
                   ....}) 
    }  *
   render() {  
     return (
        <div>
   <IntegrationDownshift Members={this.state.Data}/>
       </div>
     );
  }
 }

export default App;

您可以向 parent 组件添加一个函数,该函数将检索 child 个组件值。

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")}/>

道具可以是函数,例如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")
}

这会在每个渲染中调用 onDataChanged 属性,这没有什么意义,更有可能它应该只在子进程的 事件处理程序中 中调用。

您可以使用 props.

将 parent 函数传递给 childred

这意味着您可以在子组件中调用父函数。

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 组件

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