【问题标题】:how to pass the data from child component to parent component如何将数据从子组件传递到父组件
【发布时间】:2019-06-28 20:06:27
【问题描述】:

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

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

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 功能,它是物质 UI。我能够将值从父母发送给孩子。但它不会回到父母身边。

现在我想读取 app.js 中的 members 值。有没有办法读取 app.js 中的数据

【问题讨论】:

    标签: javascript reactjs material-ui react-component


    【解决方案1】:

    您可以向父组件添加一个函数,该函数将检索子组件的值。

    父母

      handleChildData = (value) => {
         do whatever you want to do with it
      }
    
     <IntegrationDownshift Members={this.state.Data} getData={this.handleChildData}/>
    

    孩子

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

    【讨论】:

    • 嗨,Emil,永远不会调用 getData 函数
    • @Emil 就是一个很好的例子。你可以使用类和钩子来做到这一点。
    • 在子组件中进行一些操作后,我不应该将 childData 作为静态值,然后结果应该传递给父组件。
    • 在这里你可以在 HTML 部分看到我的代码jsfiddle.net/h7evw1dq/1
    • 您可以在子组件中添加另一个函数并将其传递给 getData 参数,而不是“test”,例如 childData={props.getData(manageData())}/>,然后在 manageData返回你想要的值。
    【解决方案2】:

    您可以使用props 将父函数传递给子函数。

    也就是说你可以在子组件中调用父函数。

    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.
    }
    ...
    

    【讨论】:

    • 在这里你可以在 HTML 部分看到我的代码jsfiddle.net/h7evw1dq/1
    • 这是一个数组数据
    • @Vinoth 我更新了我的答案,您不需要将整个数组发送给父级,而只需添加一个新项目。
    • @Vinoth 然后你必须在addNewSeelctedItem 函数中更新stateData。这将rerender您的父组件和子组件,您可以看到更新的结果。
    • 嗨 antonio:如何在父组件事件中调用子方法。 stackoverflow.com/questions/56817610/…
    【解决方案3】:

    prop 可以是一个函数,例如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 属性,这没有什么意义,更有可能它应该只在子进程中在事件处理程序中调用。

    【讨论】:

    • 在子组件中进行一些操作后,我不应该将 childData 作为静态值,然后结果应该传递给父组件。
    • 在child里面的操作,你得调用props.onDataChanged(result)传给parent
    • 我试过了。我收到“props.onDataChanged 不是函数”这个错误
    • 您的代码中有多少地方使用了&lt;IntegrationDownshift /&gt;?在所有这些中,您是否通过onDataChanged 道具?拼写正确吗?
    • 在这里你可以在 HTML 部分看到我的代码jsfiddle.net/h7evw1dq/1
    【解决方案4】:

    您需要在父级中编写一个设置状态的函数,然后将该函数传递给子级。由于它绑定到父级,因此您可以在子级中运行它,并且父级的状态将被更新。

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

    【讨论】:

    • 能给个参考链接吗
    • 我不应该在子组件中进行一些操作后立即获取 childData 值,然后结果应该传递给父组件。
    猜你喜欢
    • 1970-01-01
    • 2019-02-27
    • 2017-04-20
    • 2020-04-05
    • 2017-06-25
    • 2019-06-19
    • 2022-11-23
    相关资源
    最近更新 更多