简体   繁体   中英

ReactJS: How to get state value into container?

I need to get data from DB depending on a search string value. Therefore I'm using an input field. The search string is stored as a state value.

The data for the component comes from a container (using npm meteor/react-meteor-data).

Now my problem is, how do I get the search string into the container to set the parameter for the publication?

container/example.js

export default createContainer((prop) => {
    Meteor.subscribe('images', searchString) // How to get searchString?
    return { files: Images.find({}).fetch() }
}, Example)

component/example.jsx

class Example extends Component {
    constructor(props) {
        super(props)
        this.state = {
            searchString: ''
        }
    }

    searchImage(event) {
        const searchString = event.target.value
        this.setState({ searchString })
    }

    render() {
        return (<Input onChange={ this.searchImage.bind(this) }/>)
    }
}

export default Example

publication

Meteor.publish('images', function(search) {
    return Images.find({ title: search }).cursor
})
onChange={ (e)=> {this.setState({ searchString: $(e.target).val() }) } }

This is how we assign values to our internal state properties :)

EDIT: I appear to have misunderstood the question...

Maybe you can create two different components: a parent and a child, and you can wrap child component with createContainer HOC like the following

childComponent.js

const Example = (props) => {
    return <Input onChange={props.searchImage}/>
}

export default createContainer(({searchString}) => {
Meteor.subscribe('images', searchString)
    return { files: Images.find({}).fetch() }
}, Example)

parentComponent.js

class ExampleWrapper extends Component {
    constructor(props) {
        super(props)
        this.state = {
            searchString: ''
        }
    }

    searchImage = (event)  => {
        const searchString = event.target.value
        this.setState({ searchString })
    } // instead of binding this, you can also use arrow function that 
      // takes care of binding

    render() {
        return (<Example searchImage={this.searchImage} searchString={this.state.searchString} {...this.props} />)
    }
}

export default ExampleWrapper

The idea is, since createContainer is a higher order component, it doesn't have access to the props of any component wrapped by it.

What we need to do is, passing the value of searchString from a parent component. The way to do is the following: ExampleWrapper has a state called searchString and Example component has a prop called searchString . We can set the value of searchString prop to state.searchString . Since the default export corresponds to createContainer({..some logic…}, Example}) , createContainer can make use of prop called searchString .

In order to change the value of state.searchString we also passed searchImage function as a prop to Example component. Whenever there is a change event, onChange triggers searchImage function that updates the value of state.searchString . And eventually, the minute the value of state.searchString changes searchString prop's value changes thus your subscription result also changes

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM