Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
191 views
in Technique[技术] by (71.8m points)

javascript - Is it possible to manipulate components based on the actual laid out html in Reactjs?

So I have a feeling React is just going to be the wrong tool for this job (since React is very much about one direction flow), but I figured I would ask.

Say I have the following HTML:

<div class="container">
    <div class="module">
        <div class="row">First Row</div>
        <div class="row">Second Row</div>
        <div class="row">Third Row</div>
    </div>
</div>

Now say that container class divs have a max height that only allows it to display the first and second row, causing the third flow to overflow.

When this occurs, I want to move the overflowed rows into a new container, so I have the following output:

<div class="container">
    <div class="module">
        <div class="row">First Row</div>
        <div class="row">Second Row</div>
    </div>
</div>
<div class="container">
    <div class="module">
        <div class="row">Third Row</div>
    </div>
</div>

Without React, I plan to do this by passing my data structure into a render() call, creating the html in the first code example, then iterating through each module (then row), find out if the bottom pixel value is greater than the container's max height, and if so re-render it split.

I would like to do this in Reactjs, by making each row a component that is inside a module component, but I am unsure if it's possible to accomplish this efficiently in React.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

For it to be completely dynamic would involve calculating the height of the container, and the total height of the rows one by one as they are placed. When the total height of the rows exceeds the height of the container, then we know how many rows fit in a single container, and can render as many containers as we need, each with the maximum number of rows it can handle.

This can be done using a callback on the top-level (stateful) component, this callback is passed down to the component which handles rendering individual rows, and is called after the row component has mounted. The callback then does the required calculations, then updates the state of the app with new values indicating the maximum number of rows to render per container.

Here is the rough outline of how this would work:

var App = React.createClass({

    getInitialState: function(){
        return {
           rowsToPlace: 1,
           maxRowsPerContainer: 1,
           calculateRows: true
        }
    },

    cb: function(){
        // passed down to Row component, handles calculating container/row heights
        // updates state as required
    },

    render: function(){

        // use state to incrementally render rows in to a single container 
        // until we know how many fit

        return(
            <div ClassName="app">
                {containersToRender}
            </div>
        );
    }
});

var Container = React.createClass({

    render: function(){
        return(
            <div className="container">
                <div ClassName="module">
                    {this.props.rows.map(function(row,i){
                        return <Row data={row} key={i} cb={this.props.cb} calcRows={this.props.calcRows}/>
                    }.bind(this))}
                </div>
            </div>
        );
    }

});

var Row = React.createClass({

    render: function() {
        return (
            <div className="row">{this.props.data.rowNum}</div>   
        );
    },

    componentDidMount: function(){
        if(this.props.calcRows) {
            this.props.cb();
         }
    }

});

It's not elegant, and abuses the use of state to a degree that makes me squirmish, but here is a very rough js fiddle prototype of the above in action: http://jsfiddle.net/qhuksapm/

Change the max-height of .container in the CSS to test.

At the very least it should give you something to expand on and refine.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...