Q:

How to populate state with nested child

I want to populate state like this:
state = {
    id: '1',
    parentId: null,
    text: '', // state of the root input
    child: [
        {
            id: '1.1',
            parentId: '1',
            text: '', // State of the first child input
            child: null // First child didn't have any children
        },
        {
            id: '1.2',
            parentId: '1',
            text: '', // State of the second child input
            child: null // Second child didn't have any children
        }],
};

Story:
This is a recursive problem. What I'm doing is there is a ul which render only one item i.e. a <Field /> component.
<Field /> component also has a state, a prop named id and render input element and <Quantity /> component.
<Quantity /> component generate nested list items which are nothing but a <Field /> component.
Generated <Field /> components have a correct state structure like correct id and parentId but the main problem is nested generated component has its own scope and don't care about its parent <Field /> component state.
Am I solving this problem with the wrong pattern?
Do I have to start with one stateful component <List /> which renders one stateless <Field /> component and pass all parent state as a prop on that <Field /> component?
But How to track the state?
Sandbox link 
App.jsx:
import React from 'react';
import {Field} from './components/Field';

    const App = () => {
        return (<ul className="list"><Field id='1'/></ul>);

    };

export default App;

components/Field.jsx:
import React, {Component} from 'react';
import {Quantity} from './Quantity';

export class Field extends Component {

    /**
     * @type {{id: string, text: string, parentId: (string|null), child: ([]|null)}}
     */
    state = {
        id: this.props.id,
        parentId: null,
        child: null,
        text: '',
    };

    /**
     * Handle onchange behavior of the input
     * @param target
     */
    onChangeHandler = ({target}) => {
        const {name, value} = target;
        this.setState(prevState => {
            return {[name]: value};
        });
    };

    /**
     * Trigger this function when Button of `Quantity component` is clicked
     * @param {Number} quantity - Generate array of objects with properties
     * and update state
     */
    populateChild = (quantity) => {
        // Construct new array of objects
        const data = [...Array(quantity)].map((_, index) => {
            // id => 1.1 .. 1.2 .. 1.3
            // parentId => 1
            const id = this.state.id + '.' + (index + 1);
            return {...this.state, id: id, parentId: this.state.id}
        });

        this.setState(prevState => {
            return {child: data};
        });
    };

    render() {
        return (<li>
            <div className="wrap">
                <div>
                    <label>Enter Text:</label>
                    <input type="text" name="text" onChange={this.onChangeHandler} value={this.state.text}/>
                </div>
                <div>
                    <Quantity funRef={this.populateChild}/>
                    <br/>
                    <br/>
                </div>
            </div>
            {/* Generate New unordered list only if `child` property of the state is changed.   */}
            {this.state.child !== null &&
            <ul>{this.state.child.map(element => <Field key={element.id} {...element}/>)}</ul>}
        </li>);
    };

}

components/Quantity.jsx:
import React, {Component,Fragment} from 'react';

export class Quantity extends Component {
    /**
     * @type {{min: number, quantity: number}}
     */
    state = {
        min: 0,
        quantity:0
    };

    /**
     * Handle onchange behavior of the input
     * @param target
     */
    onChangeHandler = ({target}) => {
        const val = parseInt(target.value);
        this.setState(prevState => {
            return {quantity: val};
        });
    };

    render() {
        return (
            <Fragment>
                <label>Children Quantity</label>
                <input type="number" min={this.state.min} onChange={this.onChangeHandler} value={this.state.quantity} />
                <button onClick={ () => { this.props.funRef(this.state.quantity) } }>Generate</button>
            </Fragment>
        );

    }
}

A:

Here is my stackblitz solution, note that the items state is managed into the top App component 
I decided to store the items into an array with depth = 1, it's easier to handle the updates : 
items = [
  {
    id: "1",
    parentId: null,
    text: ""
  },
  {
    id: "1.1",
    parentId: "1",
    text: ""
  },
  {
    id: "1.2",
    parentId: "1",
    text: ""
  }
];

Here is the App component :
class App extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
     items: defaultItems
    };
  }

  handleChangeText = (id, text) => {
    this.setState(prevState => ({
      items: prevState.items.map(
        item => item.id === id ? {...item, text} : item 
      )
    }));
  };

  handleAddChildren = (parentId, quantity) => {
    this.setState(prevState => {
      const childrenItems = prevState.items
        .filter(item => item.parentId === parentId);

      const otherItems = prevState.items
        .filter(item => item.parentId !== parentId);

      const childrenText = childrenItems.map(item => item.text);

      const newChildrenItems = Array.from(Array(quantity))
        .map((_, index) => ({
          parentId,
          id: `${parentId}.${index + 1}`,
          text: childrenText[index] || ""
      }));

      return {
        items: [...otherItems, ...newChildrenItems]
      };
    });
  };

  getChildren = parentId => this.state.items.filter(
      item => item.parentId === parentId
  );

  render() {
    const {items} = this.state;
    return (
      <ul>
        {
          this.getChildren(null).map(item => 
            <Field
              key={item.id}
              item={item}
              getChildren={this.getChildren}
              onChangeText={this.handleChangeText}
              onAddChildren={this.handleAddChildren}
             /> 
          )
        }
      </ul>
    );
  }
}

Here is the  Field component :
export class Field extends Component {

  handleChangeText = e => {
    const {onChangeText, item} = this.props;
    onChangeText(item.id, e.target.value);
  };

  handleGenerate = quantity => {
    const {onAddChildren, item} = this.props;
    onAddChildren(item.id, quantity);
  };

  render() {
    const {item, getChildren, onChangeText, onAddChildren} = this.props;
    const children = getChildren(item.id);

    return (
      <li>
        <div className="wrap">
          <div>
            <label>Enter Text:</label>
            <input
              type="text"
              name="text"
              onChange={this.handleChangeText}
              value={item.text}
            />
          </div>
          <div>
            <Quantity onGenerate={this.handleGenerate} />
            <br />
            <br />
          </div>
        </div>
        {children.length > 0 && (
          <ul>
            {children.map(item => (
              <Field
                key={item.id}
                item={item}
                getChildren={getChildren}
                onChangeText={onChangeText}
                onAddChildren={onAddChildren}
              />
            ))}
          </ul>
        )}
      </li>
    );
  }
}

Note that we could have created a React context to avoid passing the properties getChildren, onChangeText, onAddChildren to the Field component. 
These properties actually references functions of the top App component and are passing down to the nested Field components
Here is the solution using React.context
You just need to create a context :
const AppContext = React.createContext();

Then, you need to store the context value into the state, and wrap your App with the context. Now you just need to pass the props key and ìtem to the Field component.
constructor(props) {
  super(props);

  this.state = {
    items: defaultItems,
    contextValue: {
      onChangeText: this.onChangeText,
      onAddChildren: this.onAddChildren,
      getChildren: this.getChildren
    }
  };

}

...

render() {
  const {items, contextValue} = this.state;
  const {Provider} = AppContext;
  return (
    <Provider value={contextValue}>
      <ul>
        {
          this.getChildren(null).map(
            item => <Field key={item.id} item={item}/> 
          )
        }
      </ul>
    </Provider>
  );

}
In the Field component you can retrieve the context with static contextType = AppContext;, you can now retrieve the function onChangeText, onAddChildren, getChildren from the context
export class Field extends Component {
 static contextType = AppContext;

 handleChangeText = e => {
   const {item} = this.props;
   const {onChangeText} = this.context;

   onChangeText(item.id, e.target.value);
 };

 handleGenerate = quantity => {
   const {item} = this.props;
   const {onAddChildren} = this.context;

   onAddChildren(item.id, quantity);
 };

 render() {
   const {item} = this.props;
   const children = this.context.getChildren(item.id);

   return (
     <li>
       <div className="wrap">
         <div>
           <label>Enter Text:</label>
           <input
             type="text"
             name="text"
             onChange={this.handleChangeText}
             value={item.text}
           />
         </div>
         <div>
           <Quantity onGenerate={this.handleGenerate} />
           <br />
           <br />
          </div>
       </div>
       {children.length > 0 &&
         <ul>{children.map(item => <Field key={item.id} item={item}/>)}</ul>
       }
     </li>
   );
 }
}

