You are getting the [object Object] because the jsx tag, is something different from what you assume it to be.
First, to solve your issue, as long as FormatterComponent is a function component, you could use it as a regular function here.
function FormatterComponent(props) {
return props.value;
}
export default function App() {
return (
<span title={FormatterComponent({ value: "someValue" })}>
<FormatterComponent value={"someOtherValue"} />
</span>
);
}
which will result in:
<span title="someValue">someOtherValue</span>
In fact, as you can see, for the title you have to use the function call FormatterComponent(), while within the span element you can still use the jsx tag <FormatterComponent />.
The reason is, browsers can't utilise jsx. So it has to be transpiled by babel first, which will turn it into this ugly js.
...
function App() {
return /*#__PURE__*/React.createElement("span", {
title: FormatterComponent({
value: "someValue"
})
}, /*#__PURE__*/React.createElement(FormatterComponent, {
value: "someOtherValue"
}));
}
As you can see, event after the transpilation, for the title the function call remains, which will still result in a string. But the jsx is turned into this:
React.createElement(FormatterComponent, {
value: "someOtherValue"
}));`
The result of which is an object, that is further used by react to built up the html structure.
Keep in mind, the function call for the title, will only work while the FormatterComponent is returning a string. If it returns another jsx, you will have the same issue.
Nice to know: react without jsx.