Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript ReactJS:单击时动态添加组件_Javascript_Reactjs_Components_Dynamically Generated - Fatal编程技术网

Javascript ReactJS:单击时动态添加组件

Javascript ReactJS:单击时动态添加组件,javascript,reactjs,components,dynamically-generated,Javascript,Reactjs,Components,Dynamically Generated,我有一个菜单按钮,按下时必须添加一个新的组件。它似乎可以工作(如果我手动调用函数来添加显示的组件)。问题是,如果我单击按钮,它们不会显示,我想是因为我应该使用setState重新绘制它们。我不知道如何在另一个函数/组件中调用另一个组件的setState 这是我的index.js import React from 'react'; import ReactDOM from 'react-dom'; import './index.css'; import Menu from './Menu';

我有一个菜单按钮,按下时必须添加一个新的组件。它似乎可以工作(如果我手动调用函数来添加显示的组件)。问题是,如果我单击按钮,它们不会显示,我想是因为我应该使用setState重新绘制它们。我不知道如何在另一个函数/组件中调用另一个组件的setState

这是我的index.js

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import Menu from './Menu';
import * as serviceWorker from './serviceWorker';
import Blocks from './Block.js';


ReactDOM.render(
    <div className="Main-container">
        <Menu />
        <Blocks />
    </div>
    , document.getElementById('root'));

// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers:
serviceWorker.unregister();
从“React”导入React;
从“react dom”导入react dom;
导入“./index.css”;
从“./菜单”导入菜单;
将*作为serviceWorker从“/serviceWorker”导入;
从“/Block.js”导入块;
ReactDOM.render(
,document.getElementById('root');
//如果你想让你的应用程序离线工作并更快地加载,你可以更改
//取消注册()以在下面注册()。注意,这有一些陷阱。
//了解有关服务人员的更多信息:
serviceWorker.unregister();
然后我有了Menu.js

import React from 'react';
import './Menu.css';
import {blocksHandler} from './Block.js';

class Menu extends React.Component {

  constructor(props) {

    super(props);
    this.state = {value: ''};

    this.handleAdd = this.handleAdd.bind(this);

  }

  handleAdd(event) {
    blocksHandler.add('lol');
    console.log(blocksHandler.render());
  }

  render() {
    return (
      <div className="Menu">
        <header className="Menu-header">
          <button className="Menu-button" onClick={this.handleAdd}>Add block</button>
        </header>
      </div>
    );
  }
}

export default Menu;
从“React”导入React;
导入“/Menu.css”;
从'./Block.js'导入{blocksHandler};
类菜单扩展了React.Component{
建造师(道具){
超级(道具);
this.state={value:''};
this.handleAdd=this.handleAdd.bind(this);
}
手持式(活动){
blocksHandler.add('lol');
log(blocksHandler.render());
}
render(){
返回(
添加块
);
}
}
导出默认菜单;
最后是Block.js

import React from 'react';
import './Block.css';

// this function adds components to an array and returns them

let blocksHandler = (function() {
    let blocks = [];
    return {
        add: function(block) {
            blocks.push(block);
        },
        render: function() {
            return blocks;
        }
    }
})();

class Block extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            title: '',
            content: ''
        };

        this.handleChange = this.handleChange.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
    }

    handleChange(event) {
        this.setState({[event.target.name]: event.target.value});
    }

    handleSubmit(event) {
        alert('A name was submitted: ' + this.state.title);
        event.preventDefault();
    }

    render() {
      return (
        <div className="Block-container">
            <form onSubmit={this.handleSubmit}>
            <div className="Block-title">
                <label>
                    Block title:
                    <input type="text" name="title" value={this.state.value} onChange={this.handleChange} />
                </label>
            </div>
            <div className="Block-content">
                <label>
                    Block content:
                    <input type="text" name="content" value={this.state.value} onChange={this.handleChange} />
                </label>
            </div>
            <input type="submit" value="Save" />
            </form>
        </div>
      );
    }
}

class Blocks extends React.Component {

    render() {
        return (
            <div>
                {blocksHandler.render().map(i => (
                    <Block key={i} />
                ))}
            </div>
        )
    }
}


export default Blocks;
export {blocksHandler};
从“React”导入React;
导入“/Block.css”;
//此函数用于将组件添加到数组并返回它们
让blocksHandler=(函数(){
设块=[];
返回{
添加:功能(块){
推(块);
},
render:function(){
返回块;
}
}
})();
类块扩展了React.Component{
建造师(道具){
超级(道具);
此.state={
标题:“”,
内容:“”
};
this.handleChange=this.handleChange.bind(this);
this.handleSubmit=this.handleSubmit.bind(this);
}
手变(活动){
this.setState({[event.target.name]:event.target.value});
}
handleSubmit(事件){
警报(“已提交名称:”+this.state.title);
event.preventDefault();
}
render(){
返回(
标题栏:
块内容:
);
}
}
类块扩展了React.Component{
render(){
返回(
{blocksHandler.render().map(i=>(
))}
)
}
}
导出默认块;
出口{blocksHandler};

我是一个完全的初学者,所以我甚至不确定我的方法是否正确。感谢您提供的帮助。

您可以在Menu.js中使用BlockShandler,而不是将其作为单独的函数创建,如下所示 *

类块扩展React.Component{
建造师(道具){
超级(道具);
此.state={
标题:“”,
内容:“”
};
this.handleChange=this.handleChange.bind(this);
this.handleSubmit=this.handleSubmit.bind(this);
}
手变(活动){
this.setState({[event.target.name]:event.target.value});
}
handleSubmit(事件){
警报(“已提交名称:”+this.state.title);
event.preventDefault();
}
render(){
返回(
标题栏:
块内容:
);
}
}
Menu.js

class Menu extends React.Component {

  constructor(props) {

    super(props);
    this.state = {value: '',blocksArray:[]};

    this.handleAdd = this.handleAdd.bind(this);

  }

  handleAdd() {
   this.setState({
        blocksArray:this.state.blocksArray.push(block)
     })

  }

renderBlocks = ()=>{
      this.state.blocksArray.map(block=> <Block/>)
 }
  render() {
    return (
      <div className="Menu">
        <header className="Menu-header">
          <button className="Menu-button" onClick={()=>this.handleAdd()}>Add block</button>
        </header>
    {this.renderBlocks()}

      </div>
    );
  }
}

export default Menu;

类菜单扩展了React.Component{
建造师(道具){
超级(道具);
this.state={value:'',blocksArray:[]};
this.handleAdd=this.handleAdd.bind(this);
}
handleAdd(){
这是我的国家({
blocksArray:this.state.blocksArray.push(block)
})
}
renderBlocks=()=>{
this.state.blocksArray.map(block=>)
}
render(){
返回(
this.handleAdd()}>添加块
{this.renderBlocks()}
);
}
}
导出默认菜单;

下面,我构建了一个非常简单的父/子类型设置

父级负责呈现按钮,我在这里使用了一个简单的编号数组。当您单击任何按钮时,它将调用父级中的setState,这将导致父级重新渲染其子级

注意:我也使用了React钩子来实现这一点,我只是发现它们更多 自然和易于使用。您可以使用类,原理相同 适用

const{useState}=React;
功能儿童(道具){
const{caption}=props;
const{lines,setLines}=props.pstate;
返回{
设置行([…行,行.长度]);
}}>
{标题}
;
}
函数父级(道具){
常量[lines,setLines]=useState([0]);
返回行.map(m=>);
}
ReactDOM.render(
,document.querySelector('mount')


您可以使用道具将父级状态传递给子级,。如果将道具传递给子级包含许多子组件,则还可以使用上下文传递道具。最好的解决方案是根本不使用React state,而使用一个更健壮的状态管理系统,Redux就是为了实现这一点。谢谢你的帖子。我正在尝试学习ReactJS,添加Redux可能会让事情变得太复杂。我会查看你的链接。是的,如果你只是学习,使用Redux可能会混淆事情,。。我可能会给你一个非常简单的片段,也许会对你有所帮助
class Menu extends React.Component {

  constructor(props) {

    super(props);
    this.state = {value: '',blocksArray:[]};

    this.handleAdd = this.handleAdd.bind(this);

  }

  handleAdd() {
   this.setState({
        blocksArray:this.state.blocksArray.push(block)
     })

  }

renderBlocks = ()=>{
      this.state.blocksArray.map(block=> <Block/>)
 }
  render() {
    return (
      <div className="Menu">
        <header className="Menu-header">
          <button className="Menu-button" onClick={()=>this.handleAdd()}>Add block</button>
        </header>
    {this.renderBlocks()}

      </div>
    );
  }
}

export default Menu;