Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

支持React16的组件返回数组或简单类型的行为 #73

Closed
RubyLouvre opened this issue Nov 6, 2017 · 3 comments
Closed

支持React16的组件返回数组或简单类型的行为 #73

RubyLouvre opened this issue Nov 6, 2017 · 3 comments

Comments

@RubyLouvre
Copy link
Owner

<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <script type='text/javascript' src="./test/react.development.js"></script>
  <script type='text/javascript' src="./test/react-dom.development.js"></script>
  <script type='text/javascript' src="./lib/babel.js"></script>

</head>

<body>
  <div>开发者工具</div>
  <pre>
  </pre>
  <div id='example'></div>
  <script type='text/babel'>
   
     
      var container = document.getElementById("example")
      var div = container
     // var PropTypes = React.PropTypes
      if(!window.ReactDOM){
        window.ReactDOM = window.React
       
      }
      var PropTypes = React.PropTypes
      var expect = function(a) {
          return {
              toBe: function(b) {
                  console.log(a, "\nvs\n",b, a === b)
              }
          }
      }
      class Child extends React.Component{
        constructor(props){
          super(props)
          this.state = {
            aaa: 111
          }
        }
        componentWillMount(){
          console.log("child will mount")
        }
        componentWillUpdate(){
          console.log("child will update")
        }
        componentDidUpdate(){
          console.log("child did update")
        }
        componentDidMount(){
          console.log("child did mount")
        }
        componentWillUnmount(){
          console.log("child will unmount")
        }
        render(){
            return <strong>Child</strong>
        }
      }
      class Radio extends React.Component{
        constructor(props){
          super(props)
          this.state = {
            aaa: 111
          }
        }
        componentWillMount(){
          console.log("radio will mount")
        }
        componentWillUpdate(){
          console.log("radio will update")
        }
        componentDidUpdate(){
          console.log("radio did update")
        }
        componentDidMount(){
          console.log("radio did mount")
        }
        render(){
            return <input type="radio" />
        }
      }
      class App extends React.Component{
        constructor(props){
          super(props)
          this.state = {
            aaa: 111
          }
        }
        componentWillMount(){
          console.log("app will mount")
        }
        componentWillUpdate(){
          console.log("app will update")
        }
        componentDidUpdate(){
          console.log("app did update")
        }
        componentDidMount(){
          console.log("app did mount, setState")
          this.setState({
            aaa: 333
          })
        }
        render(){
            return this.state.aaa === 333? [<Radio/>,<Radio/>,<Radio/>] :[<Child />,<Child/>]
        }
      }
      var s = ReactDOM.render(<App /> ,div)
    </script>

</body>

</html>

image

@RubyLouvre
Copy link
Owner Author

RubyLouvre commented Nov 6, 2017

updateChildren: function (prevChildren, nextChildren, mountImages, removedNodes, transaction, hostParent, hostContainerInfo, context, selfDebugID) // 0 in production and for roots
  {
    // We currently don't have a way to track moves here but if we use iterators
    // instead of for..in we can zip the iterators and check if an item has
    // moved.
    // TODO: If nothing has changed, return the prevChildren object so that we
    // can quickly bailout if nothing has changed.
    if (!nextChildren && !prevChildren) {
      return;
    }
    var name;
    var prevChild;
    for (name in nextChildren) {
      if (!nextChildren.hasOwnProperty(name)) {
        continue;
      }
      prevChild = prevChildren && prevChildren[name];
      var prevElement = prevChild && prevChild._currentElement;
      var nextElement = nextChildren[name];
      if (prevChild != null && shouldUpdateReactComponent(prevElement, nextElement)) {
        ReactReconciler.receiveComponent(prevChild, nextElement, transaction, context);
        nextChildren[name] = prevChild;
      } else {
        if (prevChild) {
          removedNodes[name] = ReactReconciler.getHostNode(prevChild);
          ReactReconciler.unmountComponent(prevChild, false);
        }
        // The child must be instantiated before it's mounted.
        var nextChildInstance = instantiateReactComponent(nextElement, true);
        nextChildren[name] = nextChildInstance;
        // Creating mount image now ensures refs are resolved in right order
        // (see https://github.com/facebook/react/pull/7101 for explanation).
        var nextChildMountImage = ReactReconciler.mountComponent(nextChildInstance, transaction, hostParent, hostContainerInfo, context, selfDebugID);
        mountImages.push(nextChildMountImage);
      }
    }
    // Unmount children that are no longer present.
    for (name in prevChildren) {
      if (prevChildren.hasOwnProperty(name) && !(nextChildren && nextChildren.hasOwnProperty(name))) {
        prevChild = prevChildren[name];
        removedNodes[name] = ReactReconciler.getHostNode(prevChild);
        ReactReconciler.unmountComponent(prevChild, false);
      }
    }
  },


_updateChildren: function (nextNestedChildrenElements, transaction, context) {
      var prevChildren = this._renderedChildren;
      var removedNodes = {};
      var mountImages = [];
      var nextChildren = this._reconcilerUpdateChildren(prevChildren, nextNestedChildrenElements, mountImages, removedNodes, transaction, context);
      if (!nextChildren && !prevChildren) {
        return;
      }
      var updates = null;
      var name;
      // `nextIndex` will increment for each child in `nextChildren`, but
      // `lastIndex` will be the last index visited in `prevChildren`.
      var nextIndex = 0;
      var lastIndex = 0;
      // `nextMountIndex` will increment for each newly mounted child.
      var nextMountIndex = 0;
      var lastPlacedNode = null;
      for (name in nextChildren) {
        if (!nextChildren.hasOwnProperty(name)) {
          continue;
        }
        var prevChild = prevChildren && prevChildren[name];
        var nextChild = nextChildren[name];
        if (prevChild === nextChild) {
          updates = enqueue(updates, this.moveChild(prevChild, lastPlacedNode, nextIndex, lastIndex));
          lastIndex = Math.max(prevChild._mountIndex, lastIndex);
          prevChild._mountIndex = nextIndex;
        } else {
          if (prevChild) {
            // Update `lastIndex` before `_mountIndex` gets unset by unmounting.
            lastIndex = Math.max(prevChild._mountIndex, lastIndex);
            // The `removedNodes` loop below will actually remove the child.
          }
          // The child must be instantiated before it's mounted.
          updates = enqueue(updates, this._mountChildAtIndex(nextChild, mountImages[nextMountIndex], lastPlacedNode, nextIndex, transaction, context));
          nextMountIndex++;
        }
        nextIndex++;
        lastPlacedNode = ReactReconciler.getHostNode(nextChild);
      }
      // Remove children that are no longer present.
      for (name in removedNodes) {
        if (removedNodes.hasOwnProperty(name)) {
          updates = enqueue(updates, this._unmountChild(prevChildren[name], removedNodes[name]));
        }
      }
      if (updates) {
        processQueue(this, updates);
      }
      this._renderedChildren = nextChildren;

      if ("development" !== 'production') {
        setChildrenForInstrumentation.call(this, nextChildren);
      }
    },

@RubyLouvre
Copy link
Owner Author

function Unique() {
    if (typeof Set === "function") {
        return new Set();
    } else {
        return new innerSet();
    }
}
function innerSet() {
    this.array = [];
}
innerSet.prototype = {
    has: function(a) {
        return this.array.indexOf(a) > -1;
    },
    add: function(a) {
        if (!this.has(a)) {
            this.array.push(a);
        }
    }
};

@RubyLouvre
Copy link
Owner Author

在React16中stateNode代替了原来的_hostNode与_instance, return代替了_hostParent

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant