That's basically the way, short-circuit evaluation works:
As logical expressions are evaluated left to right, they are tested
for possible "short-circuit" evaluation using the following rules:
(some falsy expression) && expr is short-circuit evaluated to the
falsy expression
Thus, for an empty array, 0 is returned by the line { list.length && <div>List rendered</div> }.
While list.length is evaluated as falsy here, it is not ignored on render as opposed to false, null, undefined or true.
So, if you want your short-circuit expression to return one of the ignored values, you may return a boolean from your leftmost expression:
{ list.length>0 && <div>List rendered</div> }
Or cast the value returned by the expression to a boolean, like that:
{ !!list.length && <div>List rendered</div> }
Following is a quick demo as a proof of concept:
const { render } = ReactDOM
const Component = () => {
const list = []
return (
<div>
<div>Rendered on <code>{`list.length && <div>List rendered</div>`}</code>:{ list.length && <div>List rendered</div> }</div>
<div>Rendered on <code>{`list.length>0 && <div>List rendered</div>`}</code>:{ list.length>0 && <div>List rendered</div> }</div>
<div>Rendered on <code>{`!!list.length && <div>List rendered</div>`}</code>:{ !!list.length && <div>List rendered</div> }</div>
</div>
)
}
render (<Component />, document.getElementById('root'))
code {background-color: grey; color:white;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.12.0/umd/react.production.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.11.0/umd/react-dom.production.min.js"></script><div id="root"></div>
{ list.length ? <div>List rendered</div> : ""}should work for you.