ReactTraining / react-media

CSS media queries for React

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Conditionally set value of variable based on Media query

prateekgoel opened this issue · comments

Instead of rendering two different components based on the query, I want to set a variable whose value then I need to pass as an attribute to the component.
Because, the only difference I need for different screen size is this attribute value. It seems this is not feasible with react-media as of now. Is there any solution to this?

Could you please provide a code snippet of what you're trying to achieve?

Currently I am doing like this:

   <Media query={{ minWidth: 992 }}>
      {matches =>
        (matches ? (
          <MyComponent someAttr="value1">
            // some code here
          </MyComponent>
        ) : (
          <MyComponent someAttr="value2">
            // some code here
          </MyComponent>
        ))
      }
    </Media>

So basically, I want to have a variable set for the attribute value based on a condition. Something like below:

const attrValue = somecondition ? 'value1' : 'value2'

    <Media query={{ minWidth: 992 }}>
      {matches =>
        (matches ? (
          <MyComponent someAttr={attrValue}>
            // some code here
          </MyComponent>
        ) : (
          null
        ))
      }
    </Media>

So that I don't have to rewrite my component at two places.

@prateekgoel, I believe that your second example is works as expected, isn't it?

I've tried to make a similar demo, check this out:
https://codesandbox.io/s/ov1641xlx9

Yes this works. Sorry I think my question was a bit incorrect.
So, what I want is to evaluate value of variable based on the query condition.
Something like this:

const myVar = (
    <Media query={{ minWidth: 992 }}>
      {matches =>
        (matches ? (
          'value1'
        ) : (
          'value2'
        ))
      }
    </Media>);

Now, if I try to use this variable as an attribute to my component it gives an error because myVar don't contain a string. <Media /> returns a React element and not a string.

As this doesn't work I have to write my entire component inside <Media /> making me rewrite my entire component just to have a different attribute value.

@prateekgoel I need more context on that. Why do you even need to store that variable in that way?
Probably you don't need react-media for that? Consider to use bare using Web API

window.matchMedia()
https://github.com/ReactTraining/react-media/blob/master/modules/Media.js#L45-L46

@RusinovAnton I am using react-media at other places too in the usual way.
I need to set a variable like this at one place because my component is a grommet component, whose UI changes based on the attribute passed. So, I want to have different attribute value for different screen sizes.
Will try to use the Web API.

@RusinovAnton window.matchMedia() works. But it won't work in case of server side rendering, correct?

Yep. There is no window to match. The only way is to predict target based on User Agent or routes.

I think @RusinovAnton is right. react-media is a convenience wrapper for React, around the window.matchMedia API. If you need media queries outside of React, I don't think it makes sense to use this library.